Thrift 是一种被广泛使用的 rpc 框架,可以比较灵活的定义数据结构和函数输入输出参数,并且可以跨语言调用。为了保证服务接口的统一性和可维护性,我们需要在最开始就制定一系列规范并严格遵守,降低后续维护成本。
Thrift开发流程是:先定义IDL,使用thrift工具生成目标语言接口(interface)代码,然后进行开发。
官网:
github:https://github.com/apache/thrift/
将Thrift IDL文件编译成目标代码需要安装Thrift二进制工具。
Mac建议直接使用brew安装,节省时间:
brew install thrift安装后查看版本:
$ thrift -version Thrift version 0.12.0也可以下载源码安装,参考:。
源码地址:?path=http://www.likecs.com/thrift/0.12.0/thrift-0.12.0.tar.gz
CentOS需下载源码安装,参考:。
Debian/Ubuntu需下载源码安装,先安装依赖:,然后安装thrift:。
Windows可以直接下载二进制包。地址:?path=http://www.likecs.com/thrift/0.12.0/thrift-0.12.0.exe。
实战该小节我们通过一个例子,讲述如何使用Thrift快速开发出一个RPC微服务,涉及到Golang服务端、Golang客户端、PHP客户端、PHP服务端。项目名就叫做thrift-sample,代码托管在 https://github.com/52fhy/thrift-sample。
推荐使用Golang服务端实现微服务,PHP客户端实现调用。
编写thrift IDL thrift ├── Service.thrift └── User.thriftUser.thrift
namespace go Sample namespace php Sample struct User { 1:required i32 id; 2:required string name; 3:required string avatar; 4:required string address; 5:required string mobile; } struct UserList { 1:required list<User> userList; 2:required i32 page; 3:required i32 limit; }Service.thrift
include "User.thrift" namespace go Sample namespace php Sample typedef map<string, string> Data struct Response { 1:required i32 errCode; //错误码 2:required string errMsg; //错误信息 3:required Data data; } //定义服务 service Greeter { Response SayHello( 1:required User.User user ) Response GetUser( 1:required i32 uid ) }说明:
1、namespace用于标记各语言的命名空间或包名。每个语言都需要单独声明。
2、struct在PHP里相当于class,golang里还是struct。
3、service在PHP里相当于interface,golang里是interface。service里定义的方法必须由服务端实现。
4、typedef和c语言里的用法一致,用于重新定义类型的名称。
5、struct里每个都是由1:required i32 errCode;结构组成,分表代表标识符、是否可选、类型、名称。单个struct里标识符不能重复,required表示该属性不能为空,i32表示int32。
接下来我们生产目标语言的代码:
mkdir -p php go #编译 thrift -r --gen go thrift/Service.thrift thrift -r --gen php:server thrift/Service.thrift其它语言请参考上述示例编写。
编译成功后,生成的代码文件有:
gen-go └── Sample ├── GoUnusedProtection__.go ├── Service-consts.go ├── Service.go ├── User-consts.go ├── User.go └── greeter-remote └── greeter-remote.go gen-php └── Sample ├── GreeterClient.php ├── GreeterIf.php ├── GreeterProcessor.php ├── Greeter_GetUser_args.php ├── Greeter_GetUser_result.php ├── Greeter_SayHello_args.php ├── Greeter_SayHello_result.php ├── Response.php ├── User.php └── UserList.php注:如果php编译不加:server则不会生成GreeterProcessor.php文件。如果无需使用PHP服务端,则该文件是不需要的。
golang服务端本节我们实行golang的服务端,需要实现的接口我们简单实现。本节参考了官方的例子,做了删减,官方的例子代码量有点多,而且是好几个文件,对新手不太友好。建议看完本节再去看官方示例。官方例子:https://github.com/apache/thrift/tree/master/tutorial/go/src。
首先我们初始化go mod:
$ go mod init sample然后编写服务端代码:
main.go
编译并运行:
$ go run main.go Starting the simple server... on localhost:9090 客户端