[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

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


__EOF__

本文作者xiaowk5516
本文链接https://www.cnblogs.com/xiaowk/p/16226918.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   xiaowk5516  阅读(266)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示