<微服务架构>—Thrift篇

简介

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

macOS安装

brew install thrift

安装python thrift库

pip install thrift

使用流程

  1. 明确要交互的数据格式和具体的方法,定义出thrift接口描述文件,以thrift为后缀(英文叫作IntefaceDescription File)python

  2. 调用thrift工具,依据thrift接口文件,生成RPC代码;c++

  3. 服务器端程序引用thrift生成的RPC代码,并实现thrift中定义的逻辑,而后启动监听,等待客户端发来请求。git

  4. 客户端一样引入并调用RPC代码来与服务器端通讯

Thrift基本语法

类型

Thrift类型系统包括预约义的基本类型,用户自定义结构体,容器类型,异常和服务定义。github

基本类型(Basic types)
  • bool: 布尔类型,true或false,占1字节
  • byte: 有符号char
  • i16: 16位有符号整数
  • i32: 32位有符号整数
  • i64: 64位有符号整数
  • double: 64位浮点数
  • binary: 字符数组
  • string: 字符串(好比二进制字符串或者其余编码过的文本)
容器(Containers)
  • list: 一系列由T类型的数据组成的有序列表,元素能够重复。会被转换成C++中的vector,Java中的ArrayList,脚本语言中的数组等;
  • set: 一系列由T类型的数据组成的无序集合,元素不可重复。会转换成C++中的set,Java中的HashSet、Python中的Set等;
  • map: 一个字典结构,key为K类型,value为V类型,至关于Java中的HMap<K,V>。一个含有多个key:value键值对的结构。会被转换成C++中的map,Java中的HashMap,PHP中的关联数组,Python/Ruby中的dictionary等
结构体类型(Structs)

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;
}
服务(Services)

服务的定义,与面向对象技术中定义一个接口很相似,而这些接口其实就是纯虚函数。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

实战演练

  1. 定义接口文件example.thrift

```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-前缀的

这一步生成的代码结构以下图:
<微服务架构>—Thrift篇

  1. 参考服务端客户端源代码Github,或者直接git clone

  2. 先启动服务端python server.py,再运行客户端python client.py,输入以下:
>>>client-requets
>>>server-answer Data(text='HELLO,WORLD!', id=123)
致辞,完结,欢迎大伙到github交流学习
相关文章
相关标签/搜索