[RPC]Thrift简介
内容主要来自thrift官网,以及整合网上的文章,侵删。
参考链接:
Thrift安装
以ubuntu平台为例
下载和验证:thrift
wget https://dlcdn.apache.org/thrift/0.16.0/thrift-0.16.0.tar.gz
./configure && make -j8
具体用几个核编译,参考自己的机器
检查
make check
安装
sudo make install
Thrift类型
Thrift推荐开发者尽量使用基本类型
基本类型
类型 | 描述 |
---|---|
bool | 布尔值(true/false) |
byte | 8-bit signed integer |
i6 | 16-bit signed integer |
i32 | 32-bit signed integer |
i64 | 64-bit signed integer |
double | 64-bit floating point number |
string | 字符串(UTF-8) |
没有无符号整型
特殊类型
binary:二进制类型,string的特殊形式。
结构体
类似于面向对象语言中的对象,由key-value组成
容器
类型 | 描述 |
---|---|
list | 按序的列表,类似于vector |
set | 不按序的集合,类似于set |
map<key,value> | 类似于map |
容器不能存放服务,其他Thrift对象均可
异常
定义和struct基本一致,只是语义上有区别
服务
由一组函数组成,相当于抽象类,客户端可以调用,服务端实现具体函数定义。
其他
void类型,可以用作函数返回值,相当于没有返回值,但是服务端完成调用后仍然会发出response
oneway关键字,用于修饰void函数,客户端调用代码后不用等待响应。同一客户端的oneway方法调用可能会并行执行或者乱序执行。
Thrift IDL
Thrift Interface description language (IDL) 使用Thrift的类型定义了数据结构和服务,由Thrift代码生成器转换为目标语言支持的数据结构和接口代码。
Document
每个thrift IDL文件由0~n个headers和definitions构成,其中headers定义在definitions之前。
Header
包括Include、CppInclude和Namespace
Include
类似于pytohn中的import,可以使用引入文件中的所有结构和服务,在使用时需要加上文件名的前缀
inlcude "shared.thrift"
shared.SharedObject
cpp_include
添加一个自定义cpp文件,没有找到例子,不是很好理解
namespace
声明了Thrift IDL适用于于哪些语言
包括:
Namespace ::= ('namespace' (NamespaceScope Identifier pathname))
NamespaceScope ::= '*' | 'c_glib' | 'cpp' | 'delphi' | 'haxe' | 'go' | 'java' | 'js' | 'lua' | 'netstd' | 'perl' | 'php' | 'py' | 'py.twisted' | 'rb' | 'st' | 'xsd'
pathname ::= path
'*'表示会适用于所有支持的语言。
pathname指代路径,类似于java中的package路径
namespace cpp com.tutorial
转换为
namespace com
{
namespace tutorial
{
}
}
Definition
Definition ::= Const | Typedef | Enum | Senum | Struct | Union | Exception | Service
Const
常量
const i32 INT32CONSTANT = 9853
Typedef
别名
typedef i32 MyInteger
Enum
枚举类型,和cpp中比较接近,默认是从0开始,每个变量都比前一个大1。如果提供了非负整数,则按照提供值开始计算。不支持嵌套enum,范围在0~2^31-1。
enum Operation {
ADD = 1,
SUBTRACT = 2,
MULTIPLY = 3,
DIVIDE = 4
}
Senum
弃用
Struct
类似于cpp中的结构体,不支持嵌套struct,不支持继承
struct name{
Field*
}
struct Work {
1: i32 num1 = 0,
2: i32 num2,
3: Operation op,
4: optional string comment,
}
Union
类似于cpp中的union,每个union声明中包含多个Field,但是实例化是只含有其中一个。
union name{
Field*
}
Exception
异常,和结构体比较相似,继承自目标语言原生的异常。
union Exception{
Field*
}
Serivce
包含Thrift服务器提供的一系列功能接口,一个Serive可以在其他Serive的基础上扩充接口
'service' Identifier ( 'extends' Identifier )? '{' Function* '}'
service Calculator extends shared.SharedService {
void ping(),
i32 add(1:i32 num1, 2:i32 num2),
i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),
oneway void zip()
}
Field
可以看作是cpp中的变量
FieldID? FieldReq? FieldType Identifier ('=' ConstValue)? XsdFieldOptions ListSeparator?
FieldID: 常量正整型加上':',用于标识字段
FieldReq:
- required,必填字段
- Write: 需要写入
- Read: 可读,一定会被序列化
- Default values:需要写入
- optional
- Write: 在设置时才会被写入
- Read: 没有被写入的话,就不会被序列化
- Default values: 设置好默认值之后,没有显式写入的话,就用默认值填充。当isset标识符被设置过(域被写入或者从流中解析出来),才表示可选Feild是否设置过。
- default
- Write: 理论上是required
- Read: 类似于Optional
- Default: 可以不被写过
Function
函数
Function ::= 'oneway'? FunctionType Identifier '(' Field* ')' Throws? ListSeparator?
FunctionType ::= FieldType | 'void'
Throws ::= 'throws' '(' Field* ')'
Type
Thrift类型
FieldType ::= Identifier | BaseType | ContainerType
DefinitionType ::= BaseType | ContainerType
BaseType ::= 'bool' | 'byte' | 'i8' | 'i16' | 'i32' | 'i64' | 'double' | 'string' | 'binary' | 'slist'
ContainerType ::= MapType | SetType | ListType
MapType ::= 'map' CppType? '<' FieldType ',' FieldType '>'
SetType ::= 'set' CppType? '<' FieldType '>'
ListType ::= 'list' '<' FieldType '>' CppType?
CppType ::= 'cpp_type' Literal
常量值
ConstValue ::= IntConstant | DoubleConstant | Literal | Identifier | ConstList | ConstMap
IntConstant ::= ('+' | '-')? Digit+
DoubleConstant ::= ('+' | '-')? Digit* ('.' Digit+)? ( ('E' | 'e') IntConstant )?
ConstList ::= '[' (ConstValue ListSeparator?)* ']'
ConstMap ::= '{' (ConstValue ':' ConstValue ListSeparator?)* '}'
其他
Literal,引用
('"' [^"]* '"') | ("'" [^']* "'")
Identifier,标识符
( Letter | '_' ) ( Letter | Digit | '.' | '_' )*
STIdentifier
( Letter | '_' ) ( Letter | Digit | '.' | '_' | '-' )*
List Separator,列表分隔符
',' | ';'
Letters and Digits,字母和数字
Letter ::= ['A'-'Z'] | ['a'-'z']
Digit ::= ['0'-'9']
关键字
"BEGIN", "END", "__CLASS__", "__DIR__", "__FILE__", "__FUNCTION__",
"__LINE__", "__METHOD__", "__NAMESPACE__", "abstract", "alias", "and", "args", "as",
"assert", "begin", "break", "case", "catch", "class", "clone", "continue", "declare",
"def", "default", "del", "delete", "do", "dynamic", "elif", "else", "elseif", "elsif",
"end", "enddeclare", "endfor", "endforeach", "endif", "endswitch", "endwhile", "ensure",
"except", "exec", "finally", "float", "for", "foreach", "from", "function", "global",
"goto", "if", "implements", "import", "in", "inline", "instanceof", "interface", "is",
"lambda", "module", "native", "new", "next", "nil", "not", "or", "package", "pass",
"public", "print", "private", "protected", "raise", "redo", "rescue", "retry", "register",
"return", "self", "sizeof", "static", "super", "switch", "synchronized", "then", "this",
"throw", "transient", "try", "undef", "unless", "unsigned", "until", "use", "var",
"virtual", "volatile", "when", "while", "with", "xor", "yield"
生成代码
生成同步调用c++代码
thrift -r --gen cpp xxx.thrift
生成异步调用c++代码
thrift -r gen cpp:cob_style xxx.thrift
Thrift Protocol
主要负责序列化和反序列化。对于上层来说,输入输出是Thrift Type,进入到Protocol层,负责利用文本或者二进制进行序列化,传输到下一层中。
TBinaryProtocol
用二进制编码格式进行数据传输
TCompactProtocol
用高效率的、密集的二进制编码格式进行数据传输
TJSONProtocol
适用json文本格式进行数据传输
TSimpleJSONProtocol
只提供JSON只写的协议,适用于通过脚本语言解析
Thrift传输层
对Protocol层的数据进行拆分(TFramedTransport),同时负责和底层的网络通信进行交互
TSocket
使用阻塞式I/O进行数据传输
TNonblockingTransport
使用非阻塞式,异步方法进行数据传输
TFramedTransport
使用非阻塞方式,按块的大小进行传输