Thrift之TProtocol类体系原理及源码详细解析之其他协议类和总结

我的新浪微博:http://weibo.com/freshairbrucewoo

欢迎大家相互交流,共同提高技术。

 

第六节 其他协议类

主要的协议类基本上已经介绍完毕了,当然如果你有更好的实现和思路也可以实现自己的协议类,只要按照我前面介绍的类层次结构继承就可以了。除了前面几节介绍的协议类,Thrift还实现了一些自己内部使用的协议类,例如TDebugProtocol类,采用开发人员可读的文本协议,有助于调试,又例如TProtocolTap类,它可以使用两种协议类进行两次协议转换。放一个窃听装置在协议对象,任何读取这个类都是通过一个封闭的协议对象的,但也反映为写第二个协议对象,还有一个就是用于异常的协议类了。

到此为止,Thrift实现的协议类基本上介绍完毕了,从这些协议类的特征来看:

(1)都是实现了对外提供的统一接口,所以每一个协议类可以随时的单独使用,可以很方便的用一个协议类替换另一个协议类,对于实现都是完全独立的,协议类直接没有任何关系(继承除外);

(2)为了扩展更多的协议类提供了良好的设计方式。

第七节 总结

(1)关于定义idl的一些总结,尽量避免定义过于复杂的数据结构。

从上面的协议分析来看,复合数据类型的存在着一个递归包含的关系。不过thrift在生成封/解包的代码里,并没有出现递归调用来封/解包,而是采用了循环嵌套循环的方式来生成代码,这种做法避免了频繁递归调用封/解包函数,可提高封/解包的效率。同时带来的问题就是生成的代码量的急剧膨胀。

虽然没有递归调用来封/解包, 如果定义太过于复杂的数据结构也会随之产生多重循环,看下面的例子。假设定义以下一个数据结构:

map< string, list< set<string> > >,thrift将会产生类似于以下的循环来进行封/解包:

foreach (key in map)

{

foreach ( set in map[key] )

{

foreach (string in set )

encode()/decode();   

}

}

假设map,list,set的元素各有100个,这将是一个严重影响性能的地方,应该避免。

(2)建议使用了unsigned long long的字段使用string类型,而不是u64类型,因为目前的thrift不支持(不过好像最新版本是支持了的)。

(3)在网络IO层一个潜在的瓶颈

由于thrift的binaryprotocol协议的包头没有任何的字节描述了整个网络包的长度的信息。所以thrift的binaryprotocol协议在解包的时候是每次都只能采用从socket读取一个变量的类型接着读取变量的值出来这样的解释方式。

这种解包的方式可能引起的潜在问题:当请求的client数量非常多,交互的数据量也非常多(这里可能是交互了很多字段,或者使用了太多复合数据类型)时,tcp/ip协议栈的缓冲区可能会被塞满了还没有被处理的数据,就会严重影响服务质量。至于为何不提供某些字节来标识整个数据包的长度,是因为thrift的binaryprotocol协议需要支持复杂数据类型,像set,list,map,而这些复合数据类型的大小是难以确定的。为了支持标识整个数据包长度,封包前需要知道set,list,map的总体大小,那么就需要遍历set,list,map的大小,这是相当不划算,会增加运算逻辑,而且还会导致协议变得很复杂。

(4)如何做到兼容旧接口

当我们的server更新接口的同时,还需要保证旧client能够和新server交互,那么在定义IDL时就需要特别注意。假设,我们定义以下一个这个一个结构体来交互用户信息。

struct user

{

1:username string,

2:password string,

3:sex i16, 

}

当我们需求变更时,假设以下两种情况:

a)需要新增字段, age来表示年龄

struct user

{

1:username string,

2:password string,

3:sex i16, 

4:age i32,

}

注意,原来字段的序号标识一定不能被改变,1:username string, 不能改成 5:username string。此时,如果server是新的,client是旧的,并不影响client的工作,client从server那边收到的包里包含了age的信息,只是没有decode出来而已。

b)删除字段sex,新增字段age

struct user

{

1:username string,

2:password string,

//3:sex i16, 

4:age i32, (注意,为了保证a)所定义的client能够和b)的server交互,这里的字段序号必须定义为4)

}

此时,如果server是新的,client是a)所生成的也并不影响和b)的server交互,因为client从server那边收到的包虽然没有包含sex的信息,但是client并不会崩溃,只是缺少了sex的信息。因此,我们需求变更时,尽量保存旧的字段不要删除,做到只增不减的方式来兼容旧接口。这里字段序号是唯一标识字段的关键。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Thrift源码解析是通过分析Thrift框架的源代码来了解其内部工作原理和实现细节的过程。在这个过程中,我们可以深入了解Thrift框架中各个模块的功能和相互关系,以及具体的实现方式。 引用中提到了一篇博客文章《Thrift源码解析--Transport传输层分析》,该博客对Thrift框架中Transport传输层的实现进行了详细解析。传输层是Thrift框架中负责网络传输和数据序列化的模块,它定义了一系列的传输协议,如TBinaryProtocol、TCompactProtocol等,并提供了相应的传输方式,如TTransport、TServerTransport等。在这篇博客中,作者对Transport传输层的各个子模块进行了介绍,并详细解释了它们的实现原理和使用方法。 引用中提到了另一篇博客文章《Thrift源码解析(一)主要概述》,该博客主要介绍了Thrift框架中的一些主要和它们的作用。这些包括TProcessor、TProtocol、TServer等,它们是Thrift框架中的核心组件,负责处理数据的编码、解码、处理和传输。在这篇博客中,作者通过对这些的分析,帮助读者了解Thrift框架的整体结构和工作原理。 引用中提到了一个名为thrift-enhancer的工具包,该工具包是对Thrift协议的增强支持。它提供了动态解析IDL并生成参数对象的能力,生成的参数对象可以自动转换为Thrift协议数据,并且支持Thrift与JSON、XML的双向转换。thrift-enhancer的出现为Thrift源码解析提供了更多的工具和扩展功能,帮助开发者更好地理解和使用Thrift框架。 综上所述,Thrift源码解析是通过分析Thrift框架的源代码来了解其内部工作原理和实现细节的过程。通过阅读相关的博客文章和使用辅助工具,可以更深入地了解Thrift框架的各个模块和主要的功能和实现方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值