`
usenrong
  • 浏览: 505533 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

分布式RPC框架

    博客分类:
  • J2EE
 
阅读更多

分布式RPC框架:Polaris 
在长期的业务发展过程中,对于系统间的交互,我们使用了Socket、RMI、Hessian、JSON等技术,针对每种技术,都需要维护一套相应的故障转移、故障恢复、追踪框架,对于商业平台多条业务线的大量系统交互来说,经常面临着硬件故障问题,此种交互方式引起的维护成本及故障迁移成本都是巨大的。另外,多种不同的接口技术也面临着接口兼容性的问题,例如对于RMI来说,我们就遇到了Spring从2.5.6升级到3.1.0所带来的RMI接口不兼容导致的接口调用错误问题。最后,我们内部也有一些跨语言的调用需求,比如用C++查询广告物料信息、Python脚本做统计,这些都会涉及到接口调用,而使用不能跨语言的技术(例如RMI和Hessian)成本会非常高。因此,我们需要统一内部系统接口交互方式,并降低接口的管理和维护成本。 

在实践过程中,我们比较了WebService、ProtocolBuffer、HTTP/JSON、Dubbo以及Thrift等技术。其中,WebService基于XML,兼容性良好,但其序列化/反序列化性能较差;ProtocolBuffer和HTTP/JSON无服务接口/地址描述;Dubbo的框架过于庞大;Thrift在接口定义文档、数据类型支持、跨语言等方面存在优势,然而对服务地址和服务管理方面支持力度不够,并且存在类型侵入问题。在分析比较之后,我们选定了Thrift,并在此基础上开发了服务注册中心,解决服务地址和服务管理方面的问题。对于类型侵入问题,从描述语言来看,长远来看它生成的POJO代码应该可以像WebService一样,消除类型侵入(例如,Facebook提供了开源的Swift框架,已经朝这个方向迈进了一步)。我们目前是提供了一系列的方法和转换类,自主进行类型转换适配工作。 

我们基于Thrift构建的分布式RPC框架Polaris如图5所示。 


 

 

图 5 分布式RPC框架Polaris


我们对Polaris的服务端和客户端都进行了增强。在服务器端,我们提供了标准的HTTP服务器,能够很轻易地将一个Thrift服务发布到一个URL上。同时,也集成了标准的认证和授权框架,有效地保证了业务的安全性;另外,我们在运维监控方面做了很多增强,能够监控每个方法的执行时间以及执行参数,这样的话可以面向整个商业平台,建立标准的监控统计架构。因为我们提供的服务是基于HTTP的,因此部分统计是可以直接沿用线上已有的监控统计软件,也有效减少了重新构建监控框架的成本。 

在客户端,主要添加了失败重试、提供了类RPC的调用方式,并且提供了一种抽象的机制简化了测试成本。通过Spring的依赖注入,可以支持在仅调整配置,不改变客户端代码的情况下进行本地调用和远程HTTP调用的切换。使用本地调用时可以更快地进行单元测试,在完成单元测试之后,可以直接通过调整配置切换成远程HTTP调用,在此过程中无需任何代码的调整。此方案还对接口迁移,比如从RMI接口迁移至Thrift接口提供了很大的帮助。一般情况下,大型复杂依赖系统内部接口间的依赖关系都会特别复杂,在进行接口梳理和迁移时成本和风险都非常高,特别是在系统的服务化改造过程中需要将内部接口提升为API接口的时候。在这种情况下,可以通过引入一个Thrift模块,将此模块依赖于需要提升为API接口的模块,而其他模块则仅依赖于此Thrift模块。在此调整过程中,可以随着业务版本的开发同步进行,而且可以重用大部分单元测试稍作调整即可使用,这样的话能够将成本和风险都降至最低。 

事实上,Thrift有标准的定义语言,能够对服务接口、异常、接口参数和返回值进行描述,同时支持Set、Map之类的数据结构。然而,它没有描述服务地址以及服务依赖关系等。因此,我们也构建了服务中心Aura,它的概念架构图6所示。 


 

 

图6 服务中心Aura概念架构图


图6中的通信框架服务端和通信框架客户端已经在前面介绍了。服务中心的主要功能是对Thrift接口描述语言文件进行管理,管理其发布/订阅关系。实际上,它定义了一种团队间互相协作的方法,此协作遵循面向服务体系结构。在开发实践中,我们不鼓励依赖通过接口描述语言直接生成的代码,鼓励依赖于接口描述语言生成代码,这样能够保证耦合性,减少代码升级所带来的成本。另外,通过管理服务的所有者和服务的订阅者,能够迅速地了解到服务间的依赖关系以及服务演化时所带来的相关影响。 

在商业平台内部有多个业务系统使用分布式RPC框架Polaris,包括资金、计费、客户、财务、合同、物料、报告等,也覆盖了Java、C++、Python等语言,目前已经完成大部分接口的迁移,利用服务中心Aura,构建了完善的服务发布、发现和使用的流程,也针对其安全性、易用性和可维护性做了很多工作,因为有了一致的技术集,连怎么去使用都有了最佳实践,迁移后的服务接口显著减少了重复开发成本,有效地提升了沟通效率,降低了风险。 

分享到:
评论
3 楼 usenrong 2015-06-05  
1.tcp支持双向通信。

2.thrift基于tcp,理论上可以有这个功能,但是apache没做。原因如下。

3.thrift是rpc结构的通信框架,rpc结构默认是 【客户端请求 -> 服务端回应 -> 连接断开】 的这种短连接形式,因此rpc默认是没有服务端回调功能,自然也没有长连接。

4.虽然按照这种规范,rpc只能由客户端向服务端发起一次性的短连接服务请求,不过,一些高级rpc还是支持双向和长连接,但也要客户端先访问服务端,然后服务端才能回调客户端,比如wcf。
2 楼 usenrong 2015-06-05  
Apache Avro 与 Thrift 比较

Avro和Thrift都是跨语言,基于二进制的高性能的通讯中间件. 它们都提供了数据序列化的功能和RPC服务. 总体功能上类似,但是哲学不一样. Thrift出自Facebook用于后台各个服务间的通讯,Thrift的设计强调统一的编程接口的多语言通讯框架. Avro出自Hadoop之父Doug Cutting, 在Thrift已经相当流行的情况下Avro的推出,其目标不仅是提供一套类似Thrift的通讯中间件更是要建立一个新的,标准性的云计算的数据交换和存储的Protocol。 这个和Thrift的理念不同,Thrift认为没有一个完美的方案可以解决所有问题,因此尽量保持一个Neutral框架,插入不同的实现并互相交互。而Avro偏向实用,排斥多种方案带来的 可能的混乱,主张建立一个统一的标准,并不介意采用特定的优化。Avro的创新之处在于融合了显式,declarative的Schema和高效二进制的数据表达,强调数据的自我描述,克服了以往单纯XML或二进制系统的缺陷。Avro对Schema动态加载功能,是Thrift编程接口所不具备的,符合了Hadoop上的Hive/Pig及NOSQL 等既属于ad hoc,又追求性能的应用需求.
1 楼 usenrong 2015-06-05  
Thrift适用于程序对程序静态的数据交换,要求schema预知并相对固定。
Avro在Thrift基础上增加了对schema动态的支持且性能上不输于Thrift。
Avro显式schema设计使它更适用于搭建数据交换及存储的通用工具和平台,特别是在后台。
目前Thrift的优势在于更多的语言支持和相对成熟。

相关推荐

Global site tag (gtag.js) - Google Analytics