我的新浪微博:http://weibo.com/freshairbrucewoo。
欢迎大家相互交流,共同提高技术。
第六节其他协议类
主要的协议类基本上已经介绍完毕了,当然如果你有更好的实现和思路也可以实现自己的协议类,只要按照我前面介绍的类层次结构继承就可以了。除了前面几节介绍的协议类,Thrift还实现了一些自己内部使用的协议类,例如TDebugProtocol类,采用开发人员可读的文本协议,有助于调试,又例如TProtocolTap类,它可以使用两种协议类进行两次协议转换。放一个装置在协议对象,任何读取这个类都是通过一个封闭的协议对象的,但也反映为写第二个协议对象,还有一个就是用于异常的协议类了。
到此为止,Thrift实现的协议类基本上介绍完毕了,从这些协议类的特征来看:
(1)都是实现了对外提供的统一接口,所以每一个协议类可以随时的单独使用,可以很方便的用一个协议类替换另一个协议类,对于实现都是完全独立的,协议类直接没有任何关系(继承除外);
(2)为了扩展更多的协议类提供了良好的设计方式。
第七节总结
(1)关于定义idl的一些总结,尽量避免定义过于复杂的数据结构。
从上面的协议分析来看,复合数据类型的存在着一个递归包含的关系。不过thrift在生成封/解包的代码里,并没有出现递归调用来封/解包,而是采用了循环嵌套循环的方式来生成代码,这种做法避免了频繁递归调用封/解包函数,可提高封/解包的效率。同时带来的问题就是生成的代码量的急剧膨胀。
虽然没有递归调用来封/解包,如果定义太过于复杂的数据结构也会随之产生多重循环,看下面的例子。假设定义以下一个数据结构:
map<string,list<set<string>>>,thrift将会产生类似于以下的循环来进行封/解包:
foreach(keyinmap)
{
foreach(setinmap[key])
{
foreach(stringinset)
encode()/decode();
}
}
假设map,list,set的元素各有100个,这将是一个严重影响性能的地方,应该避免。
(2)建议使用了unsignedlonglong的字段使用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时就需要特别注意。假设,我们定义以下一个这个一个结构体来交互用户信息。
structuser
{
1:usernamestring,
2:passwordstring,
3:sexi16,
}
当我们需求变更时,假设以下两种情况:
a)需要新增字段,age来表示年龄
structuser
{
1:usernamestring,
2:passwordstring,
3:sexi16,
4:agei32,
}
注意,原来字段的序号标识一定不能被改变,1:usernamestring,不能改成5:usernamestring。此时,如果server是新的,client是旧的,并不影响client的工作,client从server那边收到的包里包含了age的信息,只是没有decode出来而已。
b)删除字段sex,新增字段age
structuser
{
1:usernamestring,
2:passwordstring,
//3:sexi16,
4:agei32,(注意,为了保证a)所定义的client能够和b)的server交互,这里的字段序号必须定义为4)
}
此时,如果server是新的,client是a)所生成的也并不影响和b)的server交互,因为client从server那边收到的包虽然没有包含sex的信息,但是client并不会崩溃,只是缺少了sex的信息。因此,我们需求变更时,尽量保存旧的字段不要删除,做到只增不减的方式来兼容旧接口。这里字段序号是唯一标识字段的关键。
分享到:
相关推荐
thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码...
Apache Thrift Java实战源码,包含了客户端和服务端源码,客户端和服务端是分开的,如果需要放到一个工程,直接把Client.java文件复制到服务端运行即可。
thrift0.9.1版本的jar包,还有源码,可供大家参考学习使用。
使用wireshark抓取thrift协议接口调用
thrift源码+DEMO+简单教程
windows下vs2010完美编译thrift,包含lib文件和src源码,thrift版本为thrift-0.11.0
thrift实现http协议案例,thrift官方好像就一个socket,此案例是通过继承servlet实现http协议通信
thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, ...
详细介绍了Apache Thrift在Ubuntu以及Windows下基于C++和Java语言的安装和运行。附有小例子,亲自测试通过。所述方法网上应该有教程,但大多零散不统一或者不完整,因此本人整理了一份,特来分享。
libthrift-1.0.0.jar,thrift例子,thrift源码 里面有你想要java版的thrift全部文件
thrift官方代码+与dubbo集成支持原生thrift协议
thrift是一种可伸缩的跨语言服务的发展软件框架。它结合了功能强大的软件堆栈的代码生成引擎,以建设服务,工作效率和无缝地与C + +,C#,Java,Python和PHP和Ruby结合。thrift是facebook开发的,我们现在把它作为...
thrift,Apache Thrift 0.9.2 版本,解压后直接直接安装,可伸缩的跨语言服务开发框架,命令: 解压命令:tar -zxf thrift-0.9.2.tar.gz 安装命令:./configure --with-lua=no && make && make install 查看版本:...
thrift-enhancer是一组支持thrift协议的加强包,设计...thrift-translator: 提供动态解析idl并生成参数对象的能力,动态生成的参数对象可以自动转换为thrift协议数据,同时提供 thrift与json、xml的双向转换, 动态解析
本设计源码提供了一个基于Scala的Spark Thrift Server。项目包含12731个文件,主要使用Scala、Java、Python、Shell、JavaScript、CSS、HTML、Ruby和C编程语言。文件类型包括3539个Scala源代码文件、1559个Q文件、...
flume通过thrift协议收集日志-Python。博客地址:http://blog.csdn.net/wangshuwei5/article/details/48902757
spark-hive_2.11-2.3.0...spark-hive-thriftserver_2.11-2.3.0.jar log4j-2.15.0.jar slf4j-api-1.7.7.jar slf4j-log4j12-1.7.25.jar curator-client-2.4.0.jar curator-framework-2.4.0.jar curator-recipes-2.4.0.jar
NULL 博文链接:https://andilyliao.iteye.com/blog/1931911
thrift文件生成工具thrift-0.9.1.exe和thrift-0.9.2.exe压缩包
不要认为thrift能在*.thrift文件中定义调度之类的工作 thrift通过IDL(接口描述语言)来生成各种语言需要的接口代码。 执行thrift文件命令: java:thrift-0.9.1.exe --gen java test.thrift java:thrift-0.9.1.exe ...