通俗易懂的理解rpc

作者:郑大侠
链接:https://www.zhihu.com/question/25536695/answer/134976748
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

RPC简单的来说就是像调用本地服务一样调用远程服务。

 

那么,netty是什么东西呢,跟RPC有什么关系?

Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序

RPC要做到用户无感知的调用远程服务必定要经过网络传输,而netty正好是是Java编写的快速开发高性能高可靠性的网络编程框架。

 

目前使用netty作为传输层的RPC框架很多,国内知名的有dubbo,motan等。

 

下面以新浪开源的motan为例,说明netty在RPC的位置:

下图中transport即使使用netty实现的。

通俗易懂的理解rpc

 

总结来说,netty就是解决RPC网络传输的。


 

分布式RPC需要解决哪些问题呢?

  1. protocol:传输协议
  2. proxy:client代理,服务引用方调用方法通过代理发送远程消息
  3. codec:协议编解码压缩等
  4. transport:协议传输
  5. registry:注册中心,服务注册服务发现
  6. cluster:负载均衡,服务容错策略
  7. 其他:服务降级,服务隔离,服务治理

如何实现一个分布式的RPC框架呢?

现在互联网已经很少单点服务了,一个好的rpc框架能帮我们省掉很多工作,那么如何撸一个自己喜欢的RPC框架呢?

现在写rpc框架已经不难了,我们可以有很多参考,很多成熟的第三方开源项目可以依赖,可以说是站在巨人的肩膀上。

第一步,选择传输协议:

高性能的rpc和良好的编码协议是分不开的。好的协议不仅耗用流量小,而且序列化和反序列化更快。

现在比较流行的协议有thrift,protobuf,json,restful等。其中thrfit和protobuf性能都比较优异,而且占用空间小,最重要的是跨语言,具有语言平台无关性。但,美中不足的是他们都需要预先根据协议文件预先生成好代码。开发极不流畅。

我们也可以自定义协议,像dubbo和motan一样,定制自己的私有协议,

比如motan协议的header部分如下:

通俗易懂的理解rpc

 

body部分采用hession或者fastjson序列化,

如果不考虑跨语言,这种算是比较完美的解决方案。

 

定义协议过程中的一些重要且容易忽略的问题:

  • 协议版本号
  • 消息id
  • 协议扩展字段

第二步,协议传输层

一个高性能RPC框架最重要的四个点就是:传输协议,框架线程模型,IO模型,零拷贝。

java程序如果能做好这四点,那么性能应该不会比c++程序差多少。

而作为java开发者,netty正好解决了后三个点,所以使用netty作为RPC框架的传输层会事半功倍。

第三部,注册中心的选择

现在有很多提供服务注册发现的服务,实现成本比较低就是zookeeper,可以很容易的实现服务注册和服务发现的功能。

 

解决了这三部,后面的就得脚踏实地码代码了,当然后续会有很多细节,不过都不是问题,现在有好多成熟的开源框架可以参考。