Thrift由Facebook研发,主要用于各个服务之间的RPC通讯(与上篇博客:gRPC同类),支持跨语言,经常使用的语言好比C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml都支持。Thrift是一个典型的 CS(客户端/服务端) 结构,在服务器端实现代码,提供接口;客户端能够直接调用接口,客户端和服务端可使用不一样的语言开发。既然客户端和服务端能使用不一样的语言开发,那么必定就要有一种中间语言来关联客户端和服务端的语言,没错,这种语言就是IDL(Interface Description Language)html
# 下载安装包 curl -# -O http://archive.apache.org/dist/thrift/0.9.2/thrift-0.9.2.tar.gz # 下载完成后开始解压 tar zxvf thrift-0.9.2.tar.gz # 进入文件夹 cd thrift-0.9.2 # 初始化配置 ./configure # 开始构建 make # 必定要用sudo,本机编译 sudo make install # 查看thrift是否生效 thrift --version # 显示:Thrift version 0.9.2
brew install thrift
pip install thrift
明确要交互的数据格式和具体的方法,定义出thrift接口描述文件,以thrift为后缀(英文叫作IntefaceDescription File)python
调用thrift工具,依据thrift接口文件,生成RPC代码;c++
服务器端程序引用thrift生成的RPC代码,并实现thrift中定义的逻辑,而后启动监听,等待客户端发来请求。git
Thrift类型系统包括预约义的基本类型,用户自定义结构体,容器类型,异常和服务定义。github
Thrift结构体类型在概念上相似于C语言中结构体类型,Thrift结构体将会被转换成面向对象语言中的类。
```c++
struct People {
1: required string name;
2: required i32 age = 20;
3: optional string sex;
}shell
能够看到,结构体中每个域都有一个正整数标识符,这个标识符并不要求连续,但一旦定义,不建议再进行修改 另外,每一个域前都会有required或optional的限定,前者表示是必填域,后者则表示是可选域。域是能够有默认值的,好比上例中的“age"。 若是一个域设置为optional且在构造结构体时没有给这个域赋值,那么在使用这个结构体时,就会忽略掉这个optional的域 #### 异常(Exceptions) 异常在语法和功能上相似于结构体,一个差异是异常使用关键字exception而不是struct来声明。但他们在语义上有明显不一样之处:当定义一个RPC服务时,咱们能够声明一个远程方法可以抛出一个异常。 ```c++ exception RequestException { 1: i32 code; 2: string reason; }
服务的定义,与面向对象技术中定义一个接口很相似,而这些接口其实就是纯虚函数。thrift编译工具会根据服务的定义来产生相应的方法和函数。
每一个服务,都包括了若干个函数,每一个函数包括了若干参数和一个返回值(返回值能够是void.
(小技巧:返回值为void的函数,你能够在函数名前加上oneway标识符,将此函数以异步模式执行,这样在调用此函数后,函数会当即返回。)apache
对于返回void的函数,thrift仍然会确保函数返回,这样就表示这个函数已被正确执行,且服务器端已有返回信息了。可是若是给void的函数前加上oneway,那么此函数的返回只能表示数据已经进入传输层,并不能表示服务器端已经收到并返回了数据数组
```c++
service vulgar_detect{
bool is_vulgar(1:string title),
i32 calc(1: i32 num)
}服务器
##### 传输协议 在传输协议上整体划分为文本和二进制 ,为节约带宽,提升传输效率,通常状况下使用二进制类型的传输协议为多数. * TBinaryProtocol — 二进制编码格式进行数据传输 * TCompactProtocol — 高效率的、密集的二进制编码格式进行数据传输 * TJSONProtocol — 使用 JSON 的数据编码协议进行数据传输 * TSimpleJSONProtocol — 只提供 JSON 只写的协议,适用于经过脚本语言解析 * TDebugProtocol – 使用易懂的可读的文本格式,以便于 debug ##### 数据传输 * TSocket — 使用阻塞式 I/O 进行传输,是最多见的模式 * TFramedTransport — 使用非阻塞方式,按块的大小进行传输 * TNonblockingTransport — 使用非阻塞方式,用于构建异步客户端 * TMemoryTransport – 将内存用于 I/O * TZlibTransport – 使用 zlib 进行压缩, 与其余传输方式联合使用 * TFileTransport – 以文件形式进行传输 ##### 服务端类型 * TSimpleServer — 单线程服务器端使用标准的阻塞式 I/O * TThreadPoolServer —— 多线程服务器端使用标准的阻塞式 I/O * TNonblockingServer —— 多线程服务器端使用非阻塞式 I/O #### thrift编译工具 在咱们编写好thrift接口描述文件以后,thrift编译工具就要派上用场了,它的做用就是根据thrift接口描述文件来生成相应开发语言的RPC代码. 在终端下输入: ```shell thrift --gen ${开发语言} ${thrift接口描述文件}
关于thrift的更多命令能够输入:多线程
thrift --help
```c++
namespace py example
struct Data {
1: string text
2: i32 id
}
service format_data {
Data do_format(1:Data data),
}
2. 用thrift命令编译example.thrift文件生成python代码 ```shell thrift -out . --gen py example.thrift # 参数说明: -out .:表示生成的代码在当前目录,而且命名不带gen-前缀,若是用-o参数是带有gen-前缀的
这一步生成的代码结构以下图:
参考服务端客户端源代码Github,或者直接git clone
python server.py
,再运行客户端python client.py
,输入以下:>>>client-requets >>>server-answer Data(text='HELLO,WORLD!', id=123)