75

分布式系统中的必备良药 —— RPC - Zachary_Fan - 博客园

 6 years ago
source link: http://www.cnblogs.com/Zachary-Fan/p/rpc_overview.html?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

  在上一篇分布式系统系列中《分布式系统中的必备良药 —— 服务治理》中阐述了服务治理的一些概念,那么与服务治理配套的必然会涉及到RPC框架。在当前互联网的大背景下,RPC的运用应该大家或多或少都有涉及,国内外的RPC框架也是百花齐放。那么各个RPC框架各自有什么特点,另外RPC的核心点又是哪些,我们该如何去选择是本文需要讲述的内容。本文会围绕.Net技术栈来展开,暂不讨论诸如dubbo之类对.Net 不太友好的框架。

二、成熟的解决方案

  1.Google.gRpc(https://github.com/grpc/grpc

    大名鼎鼎的Google出品的RPC框架,基于Http2设计,支持双向流、消息头压缩、单 TCP 的多路复用、服务端推送等特性,这些特性使得 gRPC 在移动端设备上更加省电和节省网络流量。使用的时候需要通过定义proto文件生成客户端和服务端代码,可以跨平台(客户端和服务端生成代码时使用不同的语言)。如果大家已经被微软宠惯了,那么是不太习惯以一个纯txt方式编辑这个proto文件的,毕竟全部需要手打 ╮(╯_╰)╭

  2.Facebook.Thrift(https://github.com/apache/thrift

    同样是大厂Facebook出品的RPC框架,使用方式和gRpc类似,需要通过定义.thrift文件生成客户端和服务端代码,可以跨平台(客户端和服务端生成代码时使用不同的语言)。Thrift的缺点是无法生成async,await,Task<T>之类的泛型代码,这个对于当下大背景来说有一定的局限性(如果有小伙伴知道如何解决此问题,感谢赐教)。Thrift最大的特点是5种适用不同场景的服务模型,一图胜千言,直接上图,见图1:

397048-20171213170959207-1740385710.png

     但是遗憾的是Apache在.Net下提供的实现并不是上面的5种模式,仅仅3种(TSimpleServer、TThreadPoolServer、TThreadedServer),特别是在Java下大规模宣传的NIO模式没有提供实现。

  3.Orleans(http://dotnet.github.io/orleans/

    这是微软在2015开源的构建分布式应用的框架。(什么意思?那它是RPC框架么?)我想这是大部分对Orleans不熟悉的同学的疑问,实际上Orleans的层次比RPC框架更高,它不仅仅解决了远程调用问题,其内部还包含了服务发现、负载均衡、高可用等一些处理机制。一般用Akka(有.net版本 Akka.net)和它对标,都是基于Actor模型设计的分布式框架,顺手附上一篇经典的对比文章:https://github.com/akka/akka-meta/blob/master/ComparisonWithOrleans.md 。Orleans最大的特点就是微软一向的风格,高度封装,提高生产力。面向OOP的设计,便于使用,大家可以在文末下载Demo感受一下,手感和WCF比较类似。

  4.WCF

    这应该是.net系下做分布式系统开发中的RPC标配了,随着.net framework3.5在2007年推出,可谓功能丰富,而且支持的协议相比其它框架也是最多(没有之一)。

  5.WebApi

    这是随着VS2012一起推出的REST化API的一项web服务。近几年随着整个大环境的变化,逐渐有代替WCF的趋势。跨平台(特别是针对移动端有很大优势)、便于开放共享和测试是他相对WCF的最大优势。

   上面的这些框架说不上孰优孰劣,都有各自适用的场景。那么我们来刨析一下如果要选择哪个RPC框架更适合的话从何处入手。一个RPC框架核心的概念是下面几个:

网络协议:

  这是RPC框架的核心,面向什么协议去设计,基本上也已经决定了框架最理想的适用场景了。协议又分为2个大类,分别对应OSI七层模型的应用层(http协议、ftp协议等)和传输层(tcp协议、udp协议)。这其中的协议又有各自的特点,这里就不展开说了。当然有些框架将协议这层做成可适配的,比如WCF(不同协议)、thrift(同协议不同实现),那么他们的覆盖场景肯定就更多,但是相应的框架的实现复杂度肯定也是相应增加,需要考虑是否能接收这带来的额外成本。

 序列化方式:

  序列化一般从3个维度去考虑,数据大小、可读性、传输效率(序列化反序列所消耗的时间)。属于可读性较好的序列化比如Json;属于数据压缩比比较好的序列化比如Protobuf;属于传输效率高的序列化比如MessageShark、MessagePack、Protobuf等。对于对性能十分执着的小伙伴们,这里有一份转载的基准测试报告,连接附上:https://www.cnblogs.com/shanyou/p/3294201.html 。大部分的框架都会序列化这层做成可适配的,相对网络协议,对序列化的个性化迫求是更强烈的。

四、性能测试

测试环境如下:

  CPU:I5-4300U 1.90GHz  2.50GHz

  内存:8G

  策略:10000次调用发送封装world字符串的对象HelloRequest,并等待接收返回封装Hello world字符串的HelloReply对象。

  网络:数据较小+本地调用,网络不是问题。想进一步测试局域网和大数据的可以基于文末的Demo项目自行改造。

  这里需要提一下,WCF的测试使用了http和tcp2种常见的模式,针对webapi的访问使用了HttpClient和HttpWebRequest2种方式。另外值得注意的是,由于Thrift和HttpWebRequest不支持多线程复用同一个实例,故在测试中都是使用每次实例化的方式进行(包括线程数1的时候)。

  由于数据比较多,直接付上2个动图,想进一步分析的可以在文末下载excel自行解决~。见图2,图3:

397048-20171214163817373-1860914723.gif
397048-20171214165124732-1117519097.gif

  这个是我网上找到的一篇性能相关的文章,大家可以参考一下:http://blog.csdn.net/jek123456/article/details/53395206

  归根到底,大家在使用之前还是需要结合自己的实际情况,放到实际的场景去测一把,看看效果。下面奉上替大家迈出第一步的Demo,大家可以进行进一步的深入研究。

本文相关的测试数据excel在此:https://github.com/ZacharyFan/RpcTest/raw/master/PerfTest.xlsx

本文相关的Demo地址在此:https://github.com/ZacharyFan/RpcTest

作者:Zachary
出处:https://zacharyfan.com/archives/269.html

▶关于作者:张帆(Zachary,个人微信号:Zachary-ZF)。坚持用心打磨每一篇高质量原创。欢迎扫描右侧的二维码~。

定期发表原创内容:架构设计丨分布式系统丨产品丨运营丨一些思考。

如果你是初级程序员,想提升但不知道如何下手。又或者做程序员多年,陷入了一些瓶颈想拓宽一下视野。欢迎关注我的公众号「跨界架构师」,回复「技术」,送你一份我长期收集和整理的思维导图。

如果你是运营,面对不断变化的市场束手无策。又或者想了解主流的运营策略,以丰富自己的“仓库”。欢迎关注我的公众号「跨界架构师」,回复「运营」,送你一份我长期收集和整理的思维导图。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK