当前位置:首页 > C++ > 正文

使用Apache Thrift构建C++跨语言RPC服务(C++ Apache Thrift教程与实战入门指南)

在现代分布式系统中,不同语言编写的服务之间需要高效通信。Apache Thrift 是一个由 Facebook 开源的跨语言远程过程调用(RPC)框架,支持包括 C++、Java、Python、Go 等在内的数十种编程语言。本教程将手把手教你如何使用 Apache ThriftC++ 中定义服务、生成代码并实现一个简单的客户端-服务器通信程序。无论你是初学者还是有一定经验的开发者,都能轻松上手。

使用Apache Thrift构建C++跨语言RPC服务(C++ Apache Thrift教程与实战入门指南) Thrift教程 C++ RPC框架 跨语言服务开发 Thrift入门指南 第1张

一、什么是 Apache Thrift?

Apache Thrift 是一个用于构建可扩展、跨语言服务的软件框架。它通过一个中间接口定义语言(IDL)文件来描述服务接口和数据结构,然后使用 Thrift 编译器自动生成各种语言的客户端和服务端代码。这使得用 C++ 编写的服务可以被 Python、Java 或其他语言无缝调用,极大提升了开发效率。

核心优势包括:

  • 跨语言支持(支持 C++、Java、Python、Node.js、Go 等)
  • 高性能二进制协议(如 TBinaryProtocol)
  • 多种传输方式(如 TCP、HTTP)
  • 自动生成代码,减少样板代码编写

二、安装 Apache Thrift(以 Ubuntu 为例)

首先,你需要安装 Thrift 编译器和 C++ 开发库。

# 安装依赖sudo apt-get updatesudo apt-get install -y build-essential libboost-dev libboost-test-dev \libboost-program-options-dev libevent-dev automake libtool flex bison pkg-config g++# 下载并编译 Thriftwget https://downloads.apache.org/thrift/0.19.0/thrift-0.19.0.tar.gztar -xzf thrift-0.19.0.tar.gzcd thrift-0.19.0./configure --without-python --without-java # 如果不需要其他语言绑定makesudo make install

安装完成后,运行 thrift -version 验证是否成功。

三、定义服务接口(.thrift 文件)

Thrift 使用 IDL(接口定义语言)来描述服务。创建一个名为 calculator.thrift 的文件:

namespace cpp tutorialenum Operation {  ADD = 1,  SUBTRACT = 2,  MULTIPLY = 3,  DIVIDE = 4}struct Work {  1: i32 num1,  2: i32 num2,  3: Operation op,  4: optional string comment}exception InvalidOperation {  1: i32 whatOp,  2: string why}service Calculator {  // 返回两个数的和  i32 add(1:i32 num1, 2:i32 num2),  // 执行复杂运算  i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),  // 获取服务版本  string get_version()}

这个文件定义了一个简单的计算器服务,包含加法、通用计算和获取版本号三个方法,并使用了结构体和异常。

四、生成 C++ 代码

使用 Thrift 编译器生成 C++ 代码:

thrift --gen cpp calculator.thrift

执行后会生成 gen-cpp/ 目录,里面包含:

  • Calculator.hCalculator.cpp:服务接口
  • calculator_types.h:数据结构定义
  • calculator_constants.h:常量定义

五、实现 C++ 服务端

创建 CalculatorHandler.h 实现服务逻辑:

#ifndef CALCULATOR_HANDLER_H#define CALCULATOR_HANDLER_H#include "gen-cpp/Calculator.h"#include <iostream>#include <map>class CalculatorHandler : public CalculatorIf {private:  std::map<int32_t, int32_t> log;public:  CalculatorHandler() = default;  int32_t add(const int32_t num1, const int32_t num2) override {    std::cout << "add(" << num1 << ", " << num2 << ")" << std::endl;    return num1 + num2;  }  int32_t calculate(const int32_t logid, const Work& w) override {    std::cout << "calculate(" << logid << ", {" << w.num1 << ", " << w.num2 << ", " << (int)w.op << "})" << std::endl;    int32_t val;    switch (w.op) {      case Operation::ADD:        val = w.num1 + w.num2;        break;      case Operation::SUBTRACT:        val = w.num1 - w.num2;        break;      case Operation::MULTIPLY:        val = w.num1 * w.num2;        break;      case Operation::DIVIDE:        if (w.num2 == 0) {          InvalidOperation io;          io.whatOp = w.op;          io.why = "Cannot divide by zero";          throw io;        }        val = w.num1 / w.num2;        break;      default:        InvalidOperation io;        io.whatOp = w.op;        io.why = "Invalid operation";        throw io;    }    log[logid] = val;    return val;  }  void get_version(std::string& _return) override {    _return = "Thrift C++ Tutorial v1.0";  }};#endif

六、启动服务端主程序

创建 server.cpp

#include "gen-cpp/Calculator.h"#include "CalculatorHandler.h"#include <thrift/protocol/TBinaryProtocol.h>#include <thrift/server/TSimpleServer.h>#include <thrift/transport/TServerSocket.h>#include <thrift/transport/TBufferTransports.h>using namespace ::apache::thrift;using namespace ::apache::thrift::protocol;using namespace ::apache::thrift::transport;using namespace ::apache::thrift::server;int main() {  int port = 9090;  std::shared_ptr<CalculatorHandler> handler(new CalculatorHandler());  std::shared_ptr<TProcessor> processor(new CalculatorProcessor(handler));  std::shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));  std::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());  std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());  TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);  std::cout << "Starting the server on port " << port << std::endl;  server.serve();  return 0;}

七、编译并运行

使用以下命令编译(假设所有文件在同一目录):

g++ -std=c++11 -o server server.cpp gen-cpp/*.cpp -lthrift -lpthread

启动服务:

./server

你会看到输出:Starting the server on port 9090,表示服务已启动。

八、总结与下一步

恭喜!你已经成功使用 Apache Thrift 在 C++ 中实现了一个跨语言 RPC 服务。通过这个 C++ RPC框架 教程,你掌握了从接口定义、代码生成到服务部署的完整流程。接下来,你可以:

  • 编写 Python 或 Java 客户端调用该服务(体现 跨语言服务开发 优势)
  • 尝试使用更高效的传输协议(如 TCompactProtocol)
  • 集成到实际项目中,构建微服务架构

Apache Thrift 是构建高性能、语言无关服务的强大工具。希望这篇 Thrift入门指南 能为你打开分布式系统开发的大门!

—— 本文适合初学者快速上手 Apache Thrift 与 C++ 集成开发 ——