周志明架构课-架构师视角

08.远程服务调用:如何选择适合自己的RPC框架

这一篇先来个图图:

如何选择适合自己的RPC框架?

今天就看图说话啦。

大家先想一下,世面上有很多的RPC框架,各种讲解RPC框架的教程,大家也都是有一个学一个。今天学学dubbo,明天学学gRPC的,那这些RPC都有什么共性吗?为什么会有这么多RPC呢?为什么没有一个通用的RPC框架呢?这些问题是不是大家也都想过,不过存在即有理,接下来我们就从RPC最核心的内容来看看,这些问题有没有一个答案。

RPC要解决什么问题?

看到这问题是不是有点懵圏了。RPC要解决什么问题?不就是解决远程服务通讯的问题吗?不是的这个问题的意思就是要想从0开发一个RPC,都需要解决什么问题。

1. 数据如何表示

​ 首先就是解决数据表示的问题,什么意思呢?各个语言各种操作系统都有不小的差异那怎么才能保证数据在源和在目标表示 的意义是一样的呢。这说的也就是数据如何表示 的意思了。再具体一点就是参数、返回值之类的这些玩艺儿。

​ 在明确了问题之后,是不是得想办法解决了,有什么好的解决思路呢?单纯依靠某一方肯定是不行的,至少不公平也会产生不少的纠纷。那好吧,映射到现实社会中,自然而然就是找一个大家都看好的第三方喽。不是玩笑,真的是这么个思路。

​ 因为RPC发展现在已经有很多成熟的方案的了。像gRPC的ProtocolBuffer ,web service的XML Serialization,以及很多轻量级RPC的Json Serialization都可以拿得出手的

2. 数据如何传输

​ 既然数据怎么表示这事儿咱们想明白了,那数据的传输过程又该是怎么样的呢?肯定不会是只搞一个序列化的数据流扔给底层传输协议就完事儿了,这里面需要考虑的东西太多了,像超时了怎么办,发生了异常怎么处理,安全认证怎么搞等等方面都是需要考虑的因素,不过既然能把数据如何表示这件事交给第三方,那第三方肯定也是提供了大量的解决办法的,提一个大家都比较熟悉的SOAP,它就能把这件事处理的明明白白的。

3. 方法如何表示

​ 这这这,又得解释一下了。先来对比一下本地方法的调用,本地调用某个方法,编译器会直接帮助我们把要调用的方法转换成内存中方法的入口地址,发生调用的时候你直接按顺序执行就ok了。那一换成远程调用,这点优势突然间就没了。那该怎么破呢?要不给每个方法编个号?也是一种办法哈。但更加靠谱的方法还是得搞一套与程序语言无关的接口描述语言(IDL),像WSDL,JSON-WSP都是基于这个参考这个方法来处理的。

统一的RPC搞法

怎么样,怎么样有没有发现一个问题,我好喜欢webservice那套产品呀,有了它岂不是也能一统江湖?用它来搞序列化、数据传输、接口描述,简直不能太美了。但是回过头来再瞅瞅WebService现在那副尿样子,真的是想完美想疯了,啥都很标准,啥都很规范。一点都不接地气,真正用过的人,想一想,它简单吗?它通用吗?它的性能好吗?其实通用方面我觉得做的还可以,如果大家都使用的话。可是它压根儿就没有把性能这事儿重视过哪怕一次。那你说说对得起现在这4G的网络,对得起互联网大厂飞速发展吗?更别提5G了。

​ 搞不成啊,搞不成。

​ 不过说实话,要说把简单、通用、性能都完美的结合在一起真的不是那么容易的。

RPC又要分裂了

​ 既然Web service没戏了,大家就都取多长吧。这个时候各种RPC框架就开始hi了。什么RMI、Thrift、Dubbo、gRPC等等,发展的猛的很。发展归发展,虽然很多都是在重复造轮子,但大部分都还是很有方向的,有注重性能的、有注重简单的,还有注重通用的,但是大家都不会把追求完美做为首要目标了。

​ 典型的发展方向,有这么几个:

  • 朝着面向对象发展的,比如RMI、.net Remoting,不用说这一派也是朝着通用发展
  • 朝着性能方向发展的,比如gRPC、Thrift,就是使劲儿的优化。
  • 朝着简化方向发展的,比如JSON-RPC,没别的就是简单。
  • 还有更不要脸的,朝着整合方向发展,我自己有各种组件,诶,但我也允许 你用其他RPC的组件。

总结

​ 总结一下吧,RPC要解决的三个问题是所有RPC框架都需要面临的问题,简单、通用、性能三个方面,不同的要求也有各自成熟的产品,你可以结合自己的需求选择最合适的那个,总有一款适合你。