使用Thrift来实现跨语言的方法调用
内容提要
文章介绍用Apache Thrift实现跨语言RPC调用:先编译安装Thrift,编写.thrift接口文件生成Python、C++、PHP代码,再分别实现Python和C++的服务端与客户端,并用PHP客户端调用,验证不同语言间可互相通信。
延伸解读
版本与平台差异是首要门槛
文章明确提醒,Thrift 0.13在Ubuntu 18.04上可顺利编译,但在CentOS 7.6上编译0.13却问题较多,而0.9.3反而顺利。这说明Thrift的编译安装对系统环境和版本组合敏感,读者在复现前应先确认操作系统、编译器与Thrift版本的匹配关系,避免把环境问题误判为代码问题。
接口文件是跨语言调用的契约中心
示例中所有语言共用同一份tester.thrift,通过namespace分别声明php、py、cpp命名空间,并用typedef把i32映射为Int。服务端和客户端代码都围绕这份契约生成,因此修改接口后需要重新生成各语言代码。文章也指出,PHP默认生成客户端代码,若要生成PHP服务端需额外加php:server参数。
服务端实现只需聚焦业务方法
无论Python还是C++,服务端骨架都由Thrift生成,开发者主要实现TesterHandler中的add和merge两个方法,并配置监听地址与端口。Python示例使用TSimpleServer监听127.0.0.1:9090,C++示例使用TThreadedServer监听9090。文章还演示了Python客户端调C++服务端或反之,说明跨语言互通的关键在于协议和传输配置一致。
动态库路径与编译链接容易出错
C++部分需要把libthrift.so所在目录加入LD_LIBRARY_PATH,编译时用-lthrift链接该动态库。文章特别说明,若找不到libthrift.so,很可能是依赖包缺失,可进入C++ lib目录重新make检查。对初次尝试者而言,这类链接和运行时库路径问题比接口定义更容易卡住,应按文中步骤逐项核对。
Q&A
Thrift 是什么?它最初由谁开发?
Thrift 是 Apache 基金会下的一个跨语言 RPC 框架,最初由 Facebook 开发,后来归入 Apache 基金会。它通过接口文件生成各语言代码,实现不同语言之间的方法调用。
在 Ubuntu 18.04 上编译安装 Thrift 0.13 需要哪些步骤?
先安装依赖:gcc、g++、openssl、libboost-all-dev、PHP 相关包、Python 相关包以及 Composer。然后从 GitHub 克隆源码,进入源码目录执行 ./configure --without-go --without-java --without-ruby,接着 make 和 sudo make install。安装后可用 thrift --version 验证。
如何编写 .thrift 接口文件来定义服务?
接口文件以 .thrift 命名,需定义命名空间(如 namespace php mytest、namespace py mytest、namespace cpp mytest)、类型映射(如 typedef i32 Int),以及 service 接口。例如 service Tester 中定义两个方法:Int add(1:Int num1, 2:Int num2) 和 string merge(1:string str1, 2:string str2)。
如何用 Thrift 生成 Python、C++ 和 PHP 的代码?
在接口文件所在目录执行 thrift -r --gen py tester.thrift 生成 Python 代码,thrift -r --gen cpp tester.thrift 生成 C++ 代码,thrift -r --gen php tester.thrift 生成 PHP 客户端代码。若要生成 PHP 服务端代码,需使用 thrift --gen php:server tester.thrift。
Python 服务端和客户端如何实现并运行?
服务端继承 TesterHandler 实现 add 和 merge 方法,使用 TSocket.TServerSocket 监听 127.0.0.1:9090,通过 TSimpleServer 启动。客户端创建 Tester.Client,连接同一地址,调用 add(3,4) 和 merge('Hello ','Python')。运行 python TesterServer.py 启动服务端,再运行 python TesterClient.py 即可看到结果。
C++ 服务端和客户端如何编译和运行?
服务端实现 TesterHandler 和 TesterCloneFactory,使用 TThreadedServer 监听 9090 端口。客户端创建 TesterClient 调用 add(5,6) 和 merge('Hello ','C++')。编译命令为 g++ -o TesterServer tester_constants.cpp tester_types.cpp Tester.cpp TesterServer.cpp -lthrift,客户端类似。运行 ./TesterServer 和 ./TesterClient 即可。
PHP 客户端如何调用 Python 或 C++ 的服务端?
PHP 客户端使用 TSocket 连接 localhost:9090,创建 \mytest\TesterClient,调用 add(7,8) 和 merge('Hello ','PHP')。运行 php ./TesterClient.php 即可。需先启动 Python 或 C++ 的服务端。
Thrift 支持哪些类型的服务端?有什么优势?
Thrift 支持阻塞或非阻塞的服务端程序,如 TSimpleServer、TThreadedServer 等,并支持大规模的跨语言服务开发。其优势在于能实现不同语言之间的互相调用,完全跨平台。