[RPC]Thrift简介

[RPC]Thrift简介

内容主要来自thrift官网,以及整合网上的文章,侵删。

参考链接:

Thrift安装

以ubuntu平台为例

下载和验证thrift

wget https://dlcdn.apache.org/thrift/0.16.0/thrift-0.16.0.tar.gz

编译: Building from source

./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之前。

包括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

使用非阻塞方式,按块的大小进行传输

posted @ 2022-05-05 23:29  xiaowk5516  阅读(221)  评论(0编辑  收藏  举报