提供 thrift 服务

qianmoQqianmoQ· 更新于 2026-10-05· 阅读 11 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

提供 thrift 服务

学习如何提供 thrift 服务。

thrift 是一个在各种环境中被广泛使用的 RPC 框架,最初由 Facebook 开发,后被 Apache 采纳。为了与 thrift 服务器进行交互,并解决线程安全、易用性和并发性方面的问题,brpc 直接支持 thrift 在 NonBlocking 模式下使用的 thrift 协议。

示例:example/thrift_extension_c++。

与官方方案相比的优势:

  • 线程安全。无需为每个线程设置单独的客户端。
  • 支持同步、异步、批量同步、批量异步等多种访问方式。还支持 ParallelChannel 等组合通道。
  • 支持多种连接类型(短连接、连接池)。支持超时、备份请求、取消、追踪、内置服务以及 brpc 提供的其他优势。
  • 性能更优。

编译

brpc 依赖 thrift 库,并复用 thrift 工具生成的部分代码。请阅读官方文档,了解如何编写 thrift 文件、生成代码、进行编译等。

brpc 默认不启用 thrift 支持,也不依赖 thrift 库。如需该支持,请在编译 brpc 时加上 –with-thrift 或 -DWITH\_THRIFT=ON。

在 Linux 下安装 thrift:阅读官方 wiki以安装依赖的库和工具,然后从官方站点下载 thrift 源码,解压并编译。

wget http://www.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
make CPPFLAGS=-DFORCE_BOOST_SMART_PTR -j 4 -s
sudo make install

配置 brpc 以支持 thrift,然后执行 make。编译生成的 libbrpc.a 包含用于 thrift 支持的扩展代码,可以像在其他 brpc 项目中一样正常链接。

# Ubuntu
sh config_brpc.sh --headers=/usr/include --libs=/usr/lib --with-thrift
# Fedora/CentOS
sh config_brpc.sh --headers=/usr/include --libs=/usr/lib64 --with-thrift
# Or use cmake
mkdir build && cd build && cmake ../ -DWITH_THRIFT=ON

更多编译选项请参阅快速上手](Getting-Started)。

客户端访问 thrift 服务

步骤:

  • 创建 Channel,并将协议设置为 brpc::PROTOCOL_THRIFT
  • 创建 brpc::ThriftStub
  • 直接使用原生请求与响应发起 RPC

示例代码:

#include <brpc/channel.h>
#include <brpc/thrift_message.h>         // Defines ThriftStub
...

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;
}

brpc::ThriftStub stub(&thrift_channel);
...

// example::[EchoRequest/EchoResponse] are types generated by thrift
example::EchoRequest req;
example::EchoResponse res;
req.data = "hello";

stub.CallMethod("Echo", &cntl, &req, &res, NULL);
if (cntl.Failed()) {
    LOG(ERROR) << "Fail to send thrift request, " << cntl.ErrorText();
    return -1;
}

服务端处理 thrift 请求

继承 brpc::ThriftService 来实现处理代码。可以直接调用 thrift 生成的原生 handler 以复用已有的入口,也可以像其他 protobuf 服务那样读取请求并直接设置响应。

class EchoServiceImpl : public brpc::ThriftService {
public:
    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) {
        // 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);

        res->data = req->data + " (processed)";
    }
};

将实现的服务设置到 ServerOptions.thrift_service,然后启动服务。

    brpc::Server server;
    brpc::ServerOptions options;
    options.thrift_service = new EchoServiceImpl;
    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;
    }

原生 thrift 与 brpc thrift 实现的性能对比测试

测试环境:48 核 2.30GHz

服务端返回客户端发送的字符串 “hello”

框架线程数QPS平均延迟CPU
native thrift606.9w0.9ms2.8%
brpc thrift6030w0.2ms18%

服务端返回字符串 “hello” × 1000

框架线程数QPS平均延迟CPU
native thrift605.2w1.1ms4.5%
brpc thrift6019.5w0.3ms22%

服务端执行一些复杂的数学运算后返回字符串 “hello” × 1000

框架线程数QPS平均延迟CPU
native thrift601.7w3.5ms76%
brpc thrift602.1w2.9ms93%

最后修改于 2022 年 5 月 17 日:更新 brpc 用户页面 (devlive-community/knowforge#71) (a31ce10d3)

评论

登录后参与评论

正在加载评论…