警告:本文仅仅适合初探RPC的小伙伴,对于业界老鸟的话,就不建议吐槽了。。。。
RPC服务通俗多说就是远程调用。java的rmi也是一种RPC,但是其性能与使用并不是很有好,更别说应用到分布式系统当中。于是市场上出现了很多RPC框架Dubbo、Montan、rpcx、gRPC、Thrift。说实话笔者一个都没用过 TvT 。本着学习的思想于是自己尝试的去了解这个东西,去实现这些东西。花了一周时间写出了 blackRpc这个小的rpc框架(比demo稍微高级丢丢)。我个人是觉得有辱框架这一词,望读者也表在乎这个。这里先赋上git地址:https://github.com/wangshiyu/blackRpc
设计一个RPC框架,其一得有个通信层,现在最吊的莫过于netty(这个赞,好东西啊)。由于netty5内存模型设计的缺陷被放弃,于是随便选用了一个netty4的版本。有netty保驾护航,也就成功了一半。。。其实笔者也曽写过一个阻塞式的通讯框架《sockerFly》,这个和nio实现的netty性能差距太多,于是放弃了它。其二就是spring这个万精油了,好东西,不多说。其三,一个rpc的性能最主要的两点一、通讯,二、序列化,通讯已经选用了netty,然后就是序列化。这里选择了了3种序列化方式:Json、Msgpack、Protostuff。Json做为比较实用的序列化方案,码流不大,速度相对xml什么的较快,序列化的数据可读性好。Protostuff被网上传的很神,各种性能爆表,反正我是没测试过,姑且相信。至于Msgpack,盆友说这个还可以。。。然后加进来了。当然blackRpc的序列化方式是可以扩充的,这里为了快速开发,也就没集成那么多。至此一个rpc需要的主要部件已经凑齐,至于分布式什么的后面再说,先搞个远程调用出来。
先来张简单的图,服务端发送请求,客户端返回结果,这个应该是最简单的模型了。至于怎么请求,请求什么,我们慢慢来剖析。
这下稍微复杂了丢丢,客户端的某个实例先将请求参数序列化后经过通讯模块发给服务端,服务端通讯收到信息反序列化后获取请求参数,解析找到要调用的实例,方法,然后反射调用,返回结果。这个结果也是原路返回的,图中懒得画了,各位自行脑补。这里补充说明一下,当实例1的调用请求发出之后,该线程是被阻塞在调用这里,等待结果返回时继续唤醒线程,反馈结果。也可能会调用不成功,或者超时,这里该给其反馈空,或者之机抛出异常。这样基本上一个远程调用就基本成型了。