分布式系统中的必备良药 —— RPC
阅读目录
一、前言
在上一篇分布式系统系列中《分布式系统中的必备良药 —— 服务治理》中阐述了服务治理的一些概念,那么与服务治理配套的必然会涉及到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:

【图1】
但是遗憾的是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:

【图2】

【图3】
五、结语
这个是我网上找到的一篇性能相关的文章,大家可以参考一下: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_Fan
出处:http://www.cnblogs.com/Zachary-Fan/p/rpc_overview
如果你想及时得到个人自写文章的消息推送,欢迎扫描下面的二维码~。

分布式系统中的必备良药 —— RPC的更多相关文章
- 分布式系统中的RPC请求经常出现乱序的情况 写一个算法来将一个乱序的序列保序输出
分布式系统中的RPC请求经常出现乱序的情况. 写一个算法来将一个乱序的序列保序输出.例如,假设起始序号是1,对于(1, 2, 5, 8, 10, 4, 3, 6, 9, 7)这个序列,输出是: 1 ...
- 将目录下面所有的 .cs 文件合并到一个 code.cs 文件中,写著作权复制代码时的必备良药
将目录下面所有的 .cs 文件合并到一个 code.cs 文件中,写著作权复制代码时的必备良药 @echo off echo 将该目录下所有.cs文件的内容合并到一个 code.cs 文件中! pau ...
- 分布式系统中session一致性问题
业务场景 在单机系统中,用户登陆之后,服务端会保存用户的会话信息,只要用户不退出重新登陆,在一段时间内用户可以一直访问该网站,无需重复登陆.用户的信息存在服务端的 session 中,session中 ...
- 如何在高并发分布式系统中生成全局唯一Id
月整理出来,有兴趣的园友可以关注下我的博客. 分享原由,最近公司用到,并且在找最合适的方案,希望大家多参与讨论和提出新方案.我和我的小伙伴们也讨论了这个主题,我受益匪浅啊…… 博文示例: 1. ...
- 【分布式】Zookeeper在大型分布式系统中的应用
一.前言 上一篇博文讲解了Zookeeper的典型应用场景,在大数据时代,各种分布式系统层出不穷,其中,有很多系统都直接或间接使用了Zookeeper,用来解决诸如配置管理.分布式通知/协调.集群管理 ...
- 分布式系统中一些主要的副本更新策略——Dynamo/Cassandra/Riak同时采取了主从式更新的同步+异步类型,以及任意节点更新的策略。
分布式系统中一些主要的副本更新策略. 1.同时更新 类型A:没有任何协议,可能出现多个节点执行顺序交叉导致数据不一致情况. 类型B:通过一致性协议唯一确定不同更新操作的执行顺序,从而保证数据一致性 2 ...
- 如何在高并发分布式系统中生成全局唯一Id(转)
http://www.cnblogs.com/heyuquan/p/global-guid-identity-maxId.html 又一个多月没冒泡了,其实最近学了些东西,但是没有安排时间整理成博文, ...
- (转)如何在高并发分布式系统中生成全局唯一Id
又一个多月没冒泡了,其实最近学了些东西,但是没有安排时间整理成博文,后续再奉上.最近还写了一个发邮件的组件以及性能测试请看 <NET开发邮件发送功能的全面教程(含邮件组件源码)> ,还弄了 ...
- 分布式系统中生成全局ID的总结与思考
世间万物,都有自己唯一的标识,比如人,每个人都有自己的指纹(白夜追凶给我科普的,同卵双胞胎DNA一样,但指纹不一样).又如中国人,每个中国人有自己的身份证.对于计算机,很多时候,也需要为每一份数据生成 ...
随机推荐
- linux学习(十)find命令、Linux文件后缀名、Linux和windows文件互传
一.和find相关的几个搜索命令,了解即可. 1.1 which [root@iZ25lzba47vZ ~]# which ls alias ls='ls --color=auto' /usr/bin ...
- 前端菜鸟学习之DOM事件处理
一.事件处理程序 1.DOM0级事件处理程序:就是将一个函数赋值给一个事件处理程序属性,至今仍为现代所有浏览器所支持,主要得益于其跨浏览器的优势,要使用DOM0级事件 首先要得到操作对象的引用,具体实 ...
- robotframework自动化:登陆操作
robotframework自动化系统:登录 robotframework对于编程能力比较弱的测试人员而言,真的是雪中送炭!我们可以使用robotframework根据之前完成的测试用例,一步步完善自 ...
- vue初级学习--控制台创建vue项目
一.导语 困困的我,好想睡啊,但还是敲下这边有的没的的笔记吧 二.正文 1.输入 vue list 可查看此环境下,vue能创建的项目模板 没将webpack.vue-route啃精了的话,老实用we ...
- IT屌丝如何获取改变自己的真正内心动力
要想从现在的低薪(年薪10万以下)快读变成未来的高新(年薪30万以上)我们要做的就只有从自身改变开始! 人改变自己的勇气,朱啊哟取决于我们自己当前的痛苦程度!直到某一天真的回避不了了,才会被动的改变, ...
- DbContext 中的 Explicit interface implementation
疑惑 前段时间一直再用Entity Framework 6,写了一些公用的方法,在这个过程中发现了DbContext实现的接口IObjectContextAdapter,可以通过这个接口访问到更底层的 ...
- ThreadLocal 原理解析
1.对Thread local 理解 ThreadLocal 是为了解决线程间同步而创建的一个新的思路.简单来说就是每个线程都保存一个变量副本. 如果在Thread 内部定义一个field变量,也可以 ...
- CentOS系统中出现错误--SSH:connect to host centos-py port 22: Connection refused
我在第一次搭建自己的 hadoop2.2.0单节点的伪分布集成环境时遇到了此错误,通过思考问题和查找解决方案最终搞定了这个问题,其错误原因主要有以下几种: 1)SSH服务为安装 此时,采用在线安装的方 ...
- Erlang Concurrent 并发进阶
写在前面的话 本文来源于官方教程 Erlang -- Concurrent Programming.虽然没有逻辑上的关系,但建议在掌握了Erlang入门系列教程的一些前置知识后继续阅读. 之前我是逐小 ...
- Java微信公众平台开发_07_JSSDK图片上传
一.本节要点 1.获取jsapi_ticket //2.获取getJsapiTicket的接口地址,有效期为7200秒 private static final String GET_JSAPITIC ...