Thritf 学习笔记

本文为学习记录,如有侵权,请联系删除

为何需要使用Thrift协议?

首先,Thrift是基于socket的,通过tcp协议来实现,即应用层协议

其次,现在大多使用分布式来进行架构,而实现分布式架构的方式主要是远程过程调用(Remote Procedure Call,RPC)。

简化版分布式架构:

简化版分布式架构

rpc主要需要解决的是:

  • 传输什么样的数据,用哪种协议

  • 哪种方式数据交换的效率好

  • 服务端如何处理请求

一个rpc协议一般可以分为 传输协议序列化协议。 传输协议一般是指 元信息 (我这里理解为类似与报文头),而序列化协议是指将 参数序列化(我这里理解为将报文体序列化,方便传输)

thrift协议被设计成既包含传输协议也包含序列化协议,可以很好的解决上述问题。

Thrift使用原理

结构图:

thrift 其实是包括了框架部分和协议部分。整体架构图如下:

thrift架构图.png

从上图我们可以看到,在一个层级中可以选择自己想要的,最后组合出来一个按照我们意愿的产物,也即 支持面很广

thrift核心组件:

  • TProtocol 协议和编解码组件(主要是对报文进行编码、序列化)

  • TTransport 传输组件

  • TProcessor 服务调用组件

  • TServer,Client服务器和客户端组件

  • IDL 接口定义

使用流程:

Thrift操作使用流程图

步骤如上:

  1. 创建对应的IDL文件,即(xxx.thrift)

  2. 使用IDL编译工具,将IDL文件生成对应的代码

  3. 创建对应的服务端和客户端代码(也可以在步骤2中一起生成)

Thrift 特性:

1. 基于二进制的高性能的编解码框架

  • 二进制:二进制协议比文本形式的协议,发送的数据量肯定是更小,传输效率更高的。

  • 编解码框架:作为rpc框架,一般都是封装了方法名、方法参数这些方法调用的方式。客户端发送消息。服务端接收到客户端的消息之后,解码消息,然后通过方法调用模型来完成实际服务器端业务方法的调用。

横向对比 :对比HTTP性能

从文章的测试数据可以看到,thrift的性能要远高于http。但是thrift协议的设计是比较复杂的,也不是不加判断的就使用thrift协议。基于简单程度可以选择http,基于性能可以选择thrift协议

产生这种现象的原因,一部分原因是因为非阻塞IO的机制,另一部分是http是无状态无连接的协议,而thrift协议使用前需要先建立连接,在多次传输中占有优势。

纵向对比:同比gRPC

gRPC框架的传输层是使用的http2,对比thrift主要是有更加多、更健全的文档,更优秀的鉴权功能等。但是支持广度、性能还是thrift要更胜一筹。

2. 基于NIO的底层通信

NIO,全称是NoneBlocking IO,非阻塞IO,和BIO(Blocking IO,阻塞IO)相对应。具体的解释和实现机制,不是这篇文章的重点,有兴趣可以自行查阅一下。可以看看篇文章

3. 相对简单的服务调用模型

4. 使用IDL支持跨平台调用

小结:

总结来说就是高性能、传输速度快、支持面广,可以跨平台使用

协议结构

Thrift请求相应模型

thrift请求响应模型

可以将这里的message和struct理解为报文头和报文体的关系。注意图中的1、2不是发送了两次请求,应该理解为一组字节流,2紧跟在1后面,4紧跟在3后面。

Message

Message中主要包含Name,Message Type,Sequence ID等数据。

  1. Name:为调用的方法名

  2. Message Type:有Call, OneWay, Reply, Exception四种,在实际传递的时候,传递的是Type ID,这四种Type对应的Type ID如下

     Call      ---> 1
     OneWay    ---> 2
     Reply     ---> 3
     Exception ---> 4

其中Call、OneWay用于Request, Reply、 Exception用于Response中。 四者的含义如下:

  • Call: 调用远程方法,并且期待对方发送响应。

  • OneWay: 调用远程方法,不期待响应。即没有步骤3,4。

  • Reply: 表明处理完成,响应正常返回。

  • Exception:表明出理出错。

  1. Sequence ID : 序列号, 有符号的四字节整数。在一个传输层的连接上所有未完成的请求必须有唯一的序列号,客户端使用序列号来处理响应的失序到达,实现请求和响应的匹配。服务端不需要检查该序列号,也不能对序列号有任何的逻辑依赖,只需要响应的时候将其原样返回即可。可以类比于tcp滑动窗口中的序列号来理解。

Struct

在上面的Thrift请求响应模型中,有两种Struct:

  1. Request Struct

  2. Response Struct

这两种Struct的结构是一样的,都是由多个Field组成

具体可参考这里

序列化协议

序列化本质是把 rpc的参数 转换成 一段连续的二进制流,进一步还可以对参数进行压缩(可选),使传输的流量更少。

Thrift支持多种序列化协议,常用的有: Binary、Compact、JSON。常用的是Binary和Compact。前者基本就是将参数顺序的写入连续的二进制流,后者对参数进行了一定的压缩。本文主要分析Binary,Compact有兴趣可自行查阅。

Binary序列化

binary序列化是一种二进制的序列化方式,不可读。

Message的序列化

Message的序列化分为两种,strict encoding和old encoding。 在有些实现中,会通过 检查Thrift消息的第一个bit来判断使用了那种encoding:

  • 1 —-> strict encoding (会带上Version信息,默认模式)

  • 0 —-> old encoding

官网上面是这样写的:

Thrift Protocols are stream oriented by design. There is no need for any explicit framing. For instance, it is not necessary to know the length of a string or the number of items in a list before we start serializing them. Some of the protocols available for majority of the Thrift-supported languages are:
 
 - binary: Fairly simple binary encoding – the length and type of a field are encoded as bytes followed by the actual value of the field.
 - compact: Described in [THRIFT-110](https://issues.apache.org/jira/browse/THRIFT-110)
 - json

图片来源

猜想使用三个bit的目的是为了方便后续扩展。

Struct的序列化

Struct装的是Thrift通信的实际参数,一个Struct由很多基本类型组合而成,要了解Struct怎么序列化的必须知道这些基本类型的序列化。

Binary序列化中各种字段类型的类型标记和占用大小:

数据类型 类型标志(一个字节)
bool 2 一个字节
byte 3 一个字节
double 4 八个字节
i16 6 两个字节值
i32 8 四个字节值
i64 10 八个字节值
string 11 四个字节数据长度+数据的值
binary 11 四个字节数据长度+数据的值
struct 12 多个连续的field数据+一个字节停止符(0)
map 13 一个字节的key类型标志+一个字节的val类型标志+四个字节的数据长度+数据的值(key+val)
set 14 一个字节的val类型标志+四个字节的数据长度+数据的值
list 15 一个字节的val类型标志+四个字节的数据长度+数据的值

序列化后的二进制流格式

[id(2字节) + 类型标志(1字节) + 值] +  [id(2字节) + 类型标志(1字节) + 值] + .....

由于二进制流中存在 id序号 和 类型flag, 当server收到协议后,会根据服务端注册的idl, 根据 id序号到二进制流中找对应的buffer, 并会对类型做进一步比对。

Compact

主要是对Binary进行了一点压缩

Thrift IDL使用方法

看参考Thrift IDL 使用语法

参考文章

Thrift官网

HTTP性能对比测试

同比gRPC

NIO相关基础

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容