微信号:simplemain

介绍:简单·美的程序员分享技术干货

非死不可的RPC框架:thrift

2016-08-28 12:57 简单的老王

周日下午这个老时间,老王又来扯技术了~


上周跟大家聊了聊RPC框架的原理,这周准备跟大家聊一个具体的RPC框架:facebookthrift(这周网友"Mark"给老王推荐了google的新框架gRPC,等老王后面仔细研究以后再给大家做做分享)。

 

大概是3年前,老王在研究开源RPC框架的时候,接触到了thrift,当时主要是和protobuf做对比,发现这货代码居然写的那么漂亮,于是乎就比较深入的研究了一下他。后来加入百词斩后,就把这个框架引入到了整个服务器体系中。到目前为止,已经比较稳定的运行了2年多了。用他最大的好处有几点:

 

1、实现了跨语言的交互。我们内部系统有多种语言开发(不同语言应用的场景不一样,比如有些语言开发快,适合做快速迭代的业务;有些语言执行效率高,适合做更为底层的开发等等),而语言间的逻辑调用需要有跨平台的支持。thrift刚好有我们使用的几种语言,所以多语言的问题就不再是问题;

 

2、简化了交互逻辑。原来跨系统调用的时候,一般使用http的方式进行交互。程序员之间要反复交流,针对接口反复确认。最后花了很多时间在这个上面。而且交互代码会写的比较麻烦:拼接URL参数、写调用http代码、解析调用结果,如果出错还要写重试代码。使用thrift以后,整个这些操作都被封装到框架底层:针对接口的讨论,只要给出idl,剩余的事情都让机器去确认。同时,整个开发逻辑也极大简化,基本就几行代码。

 

3、提升质量,减少bug。以前用Http的方式调用的时候,经常在测试、上线后发现bug。一追问题,我擦,参数少了一个。然后为了拼接参数,找不到说明文档,就需要去看以前别人写的代码,痛苦至极。关键,还写不对。现在用thrift,有idl这个天然的接口文档,然后用他编译出的接口文件,少一个参数都编译不通过,大大减少了因为接口参数问题出现的bug

 

好了,说了这么多好处,就让我们一起来看看他的内部架构是怎么样的吧。

 

1、整体设计逻辑

 

thrift整体的逻辑分成两大部分:

 

A、静态代码生成。使用者按照规范编写接口描述语言IDL(实际就是你的接口函数 + 实体类),然后使用thrift提供的编译器,将这个IDL编译成你想要的语言的代码。然后留出需要实现的地方,你去填写具体的实现逻辑。现在他支持的语言有很多,比如c/c++javapythonrubyc#goperl等等,甚至还支持javascript

 

Bruntime运行时。将上述生成的代码 + 他提供的库,将我们的逻辑设置成为回调,启动库里的server,就可以提供RPC服务。而客户端也是同样的方式,便能启动相关的调用。

 

所以,他的整体架构实际是分成静态部分和动态部分。静态部分需要根据不同的平台,自己编译相关的生成工具。而动态部分,需要根据自己的语言使用不同的库来启动运行。

 




2、静态部分的代码生成

 

所谓的IDL文件实际就可以看成一个特殊语言的代码(类似于c++或者java),提供服务接口和实体结构两种类型。服务接口的作用类似于函数,而实体结构类似于结构体或者是java-bean这样的东东。

 

然后thrift提供的gen工具,可以生成多种支持的语言代码。代码分成serverclient两部分。开发者需要填充server端的实现逻辑,而客户端代码则可以直接调用。

 




3、用户代码+基础库的运行时层次和逻辑

 

 

thrift的基础库充当了framework的作用,提供传输协议、数据格式协议、处理框架、服务端框架+客户端框架的基础功能;

 

之前IDL产生的代码则提供了基础的数据结构(结构体或java-bean)和固定处理流程的功能;

 

而我们要书写的逻辑部分,则被当做回调用于实际的功能实现。

 



transport层就是我们之前说的传输协议(比如:tcphttp等);

 

protocol层则是数据组织协议(比如:jsonxml等);

 

server层是我们的服务器模型,怎么样组织我们的服务器模型来保证我们能提供尽量高并发、高可用的服务能力(比如:epollselect等)。

 

4、具体每一层次的实现

 

A、传输层:位于框架的最底层,他的作用就是提供数据传输功能。在实现里,有TCPHttpFileSasl等多种实现。而TCPHttp两种方式也是我们平时写代码用的最多的方式。详细的参见下图:

 




B、数据协议:这个就是我们数据怎么样打包、怎么样解包,实现两个进程间的数据交互。比如,我们原来说过的jsonxml等都是这样的数据协议格式。thrift提供JsonBinaryCompact几种方式,其中compact方式是压缩最多的方式(大家还记得老王介绍过的zigzag算法嘛,他就出自这里)。

 




CServer模型:为了尽可能提供高效的服务,thrift也提供了好几种server模型。有simplethreadpoolhshathreadselectorsimple提供的就是一个demo,大家可以通过他看懂服务器工作原理。threadpool提供一个线程池模型,每一个请求占用一个线程。因此,如果要有大量请求的时候,就会有很多线程来服务。HsHaThreadedSelector是利用java.nio(底层用的是epoll)来做的,通过事件驱动。不同的是,readwrite是否有单独的线程来处理。

 




好了,整体thrift的框架逻辑和结构基本上就聊这么多。再次推荐大家阅读他的源代码,结构分层很清晰,代码也写的很美。如果读起来不顺畅,可以参考老王的这篇文章。等后面老王把gRPC研究完以后,再给大伙儿做个分享。

 


 
SimpleMain 更多文章 好友动态的实现原理 分布式系统的中枢Naming-Service 第一部分::任务5:总结作业-记事本 牛逼哄哄的RPC 第一部分::任务4:搭建数据库&程序同数据库连接
猜您喜欢 码农软粉购买微软新硬件的正确姿势 调度器 Scheduler(四,完结):实现 GUI 系统的 Scheduler 全民K歌增量升级方案 传统运维 VS 互联网运维:从哪来,到哪去? 你猜名次我送大礼,壕壕壕!