thrift.md 6.06 KB
Newer Older
wangxuefeng's avatar
wangxuefeng committed
1 2
[中文版](../cn/thrift.md)

3
[thrift](https://thrift.apache.org/) is a RPC framework used widely in various environments, which was developed by Facebook and adopted by Apache later. In order to interact with thrift servers and solves issues on thread-safety, usabilities and concurrencies, brpc directly supports the thrift protocol that is used by thrift in NonBlocking mode.
wangxuefeng's avatar
wangxuefeng committed
4

5 6 7
Example: [example/thrift_extension_c++](https://github.com/brpc/brpc/tree/master/example/thrift_extension_c++/).

Advantages compared to the official solution:
wangxuefeng's avatar
wangxuefeng committed
8
- Thread safety. No need to set up separate clients for each thread.
wangxuefeng's avatar
wangxuefeng committed
9
- Supports synchronous, asynchronous, batch synchronous, batch asynchronous, and other access methods. Combination channels such as ParallelChannel are also supported.
wangxuefeng's avatar
wangxuefeng committed
10
- Support various connection types(short, connection pool). Support timeout, backup request, cancellation, tracing, built-in services, and other benefits offered by brpc.
11
- Better performance.
wangxuefeng's avatar
wangxuefeng committed
12

13
# Compile
14
brpc depends on the thrift library and reuses some code generated by thrift tools. Please read official documents to find out how to write thrift files, generate code, compilations etc.
15

16
brpc does not enable thrift support or depend on the thrift lib by default. If the support is needed, compile brpc with extra --with-thrift or -DWITH_THRIFT=ON
wangxuefeng's avatar
wangxuefeng committed
17

18
Install thrift under Linux
Ge Jun's avatar
Ge Jun committed
19
Read [Official wiki](https://thrift.apache.org/docs/install/debian) to install depended libs and tools, then download thrift source code from [official site](https://thrift.apache.org/download), uncompress and compile。
wangxuefeng's avatar
wangxuefeng committed
20 21 22 23 24
```bash
wget http://www.us.apache.org/dist/thrift/0.11.0/thrift-0.11.0.tar.gz
tar -xf thrift-0.11.0.tar.gz
cd thrift-0.11.0/
./configure --prefix=/usr --with-ruby=no --with-python=no --with-java=no --with-go=no --with-perl=no --with-php=no --with-csharp=no --with-erlang=no --with-lua=no --with-nodejs=no
25
make CPPFLAGS=-DFORCE_BOOST_SMART_PTR -j 4 -s
wangxuefeng's avatar
wangxuefeng committed
26 27
sudo make install
```
wangxuefeng's avatar
wangxuefeng committed
28

29
Config brpc with thrift support, then make. The compiled libbrpc.a includes extended code for thrift support and can be linked normally as in other brpc projects.
wangxuefeng's avatar
wangxuefeng committed
30
```bash
31
# Ubuntu
32
sh config_brpc.sh --headers=/usr/include --libs=/usr/lib --with-thrift
33 34 35
# Fedora/CentOS
sh config_brpc.sh --headers=/usr/include --libs=/usr/lib64 --with-thrift
# Or use cmake
36
mkdir bld && cd bld && cmake ../ -DWITH_THRIFT=ON
wangxuefeng's avatar
wangxuefeng committed
37
```
gejun's avatar
gejun committed
38
Read [Getting Started](../cn/getting_started.md) for more compilation options.
wangxuefeng's avatar
wangxuefeng committed
39

40 41
# Client accesses thrift server
Steps:
Ge Jun's avatar
Ge Jun committed
42
- Create a Channel setting protocol to brpc::PROTOCOL_THRIFT
43 44
- Create brpc::ThriftStub
- Use native request and response to start RPC directly.
wangxuefeng's avatar
wangxuefeng committed
45

46
Example code:
wangxuefeng's avatar
wangxuefeng committed
47 48
```c++
#include <brpc/channel.h>
49
#include <brpc/thrift_message.h>         // Defines ThriftStub
wangxuefeng's avatar
wangxuefeng committed
50 51 52 53 54 55 56 57 58 59 60 61 62 63
...

DEFINE_string(server, "0.0.0.0:8019", "IP Address of thrift server");
DEFINE_string(load_balancer, "", "The algorithm for load balancing");
...
  
brpc::ChannelOptions options;
options.protocol = brpc::PROTOCOL_THRIFT;
brpc::Channel thrift_channel;
if (thrift_channel.Init(Flags_server.c_str(), FLAGS_load_balancer.c_str(), &options) != 0) {
   LOG(ERROR) << "Fail to initialize thrift channel";
   return -1;
}

64
brpc::ThriftStub stub(&thrift_channel);
65
...
wangxuefeng's avatar
wangxuefeng committed
66

67 68 69 70
// example::[EchoRequest/EchoResponse] are types generated by thrift
example::EchoRequest req;
example::EchoResponse res;
req.data = "hello";
wangxuefeng's avatar
wangxuefeng committed
71

72
stub.CallMethod("Echo", &cntl, &req, &res, NULL);
73 74 75 76
if (cntl.Failed()) {
    LOG(ERROR) << "Fail to send thrift request, " << cntl.ErrorText();
    return -1;
} 
wangxuefeng's avatar
wangxuefeng committed
77 78
```

79
# Server processes thrift requests
Ge Jun's avatar
Ge Jun committed
80
Inherit brpc::ThriftService to implement the processing code, which may call the native handler generated by thrift to re-use existing entry directly, or read the request and set the response directly just as in other protobuf services.
wangxuefeng's avatar
wangxuefeng committed
81
```c++
82
class EchoServiceImpl : public brpc::ThriftService {
wangxuefeng's avatar
wangxuefeng committed
83
public:
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
    void ProcessThriftFramedRequest(brpc::Controller* cntl,
                                    brpc::ThriftFramedMessage* req,
                                    brpc::ThriftFramedMessage* res,
                                    google::protobuf::Closure* done) override {
        // Dispatch calls to different methods
        if (cntl->thrift_method_name() == "Echo") {
            return Echo(cntl, req->Cast<example::EchoRequest>(),
                        res->Cast<example::EchoResponse>(), done);
        } else {
            cntl->SetFailed(brpc::ENOMETHOD, "Fail to find method=%s",
                            cntl->thrift_method_name().c_str());
            done->Run();
        }
    }

    void Echo(brpc::Controller* cntl,
              const example::EchoRequest* req,
              example::EchoResponse* res,
              google::protobuf::Closure* done) {
wangxuefeng's avatar
wangxuefeng committed
103 104 105 106
        // This object helps you to call done->Run() in RAII style. If you need
        // to process the request asynchronously, pass done_guard.release().
        brpc::ClosureGuard done_guard(done);

107
        res->data = req->data + " (processed)";
wangxuefeng's avatar
wangxuefeng committed
108 109 110 111
    }
};
```

Ge Jun's avatar
Ge Jun committed
112
Set the implemented service to ServerOptions.thrift_service and start the service.
wangxuefeng's avatar
wangxuefeng committed
113
```c++
114
    brpc::Server server;
wangxuefeng's avatar
wangxuefeng committed
115
    brpc::ServerOptions options;
116
    options.thrift_service = new EchoServiceImpl;
wangxuefeng's avatar
wangxuefeng committed
117 118 119 120 121 122 123 124
    options.idle_timeout_sec = FLAGS_idle_timeout_s;
    options.max_concurrency = FLAGS_max_concurrency;

    // Start the server.
    if (server.Start(FLAGS_port, &options) != 0) {
        LOG(ERROR) << "Fail to start EchoServer";
        return -1;
    }
125
```
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144

# Performance test for native thrift compare with brpc thrift implementaion
Test Env: 48 core  2.30GHz
## server side return string "hello" sent from client
Framework | Threads Num | QPS | Avg lantecy | CPU
---- | --- | --- | --- | ---
native thrift | 60 | 6.9w | 0.9ms | 2.8%
brpc thrift | 60 | 30w | 0.2ms | 18%

## server side return string "hello" * 1000
Framework | Threads Num | QPS | Avg lantecy | CPU
---- | --- | --- | --- | ---
native thrift | 60 | 5.2w | 1.1ms | 4.5%
brpc thrift | 60 | 19.5w | 0.3ms | 22%

## server side do some complicated math and return string "hello" * 1000
Framework | Threads Num | QPS | Avg lantecy | CPU
---- | --- | --- | --- | ---
native thrift | 60 | 1.7w | 3.5ms | 76%
145
brpc thrift | 60 | 2.1w | 2.9ms | 93%