手写个人rpc (序言)

144 阅读2分钟

想法

学习完netty,感觉自己的深度不足。

简易版im我也写了,但是总觉得偏理论,现实工作中,因为我个人是偏业务的后端开发,平时接触更多的是各种业务代码,自然也少不了rpc框架。

关于rpc框架,自己工作的三年多里面,feign, dubbo, sofa-rpc等都用过,之前也尝试过去阅读他们的源码,总是一会就忘了,到底他们涉及的巧妙的地方在哪里,值得我们学习的地方要在哪里?

因此通过手写一个rpc框架,再去对比优秀的开源框架,就能从中发现自己手写框架的不足,得到更多的思考,从而给工作中带来更多的启发。

再想想以前学生时代,如何真正去掌握一个知识?不就是理论 + 做题巩固 + 讲解分享嘛

理论(netty书籍,文章思路) + 做题(编码) 自己都做完了,剩下的就是讲解分享,通过博客自己来进行分析。

rpc整体框架

手写rpc client端的设计 (1).jpg

整体的框架如上图所示

其实像平时在用dubbo \ feign等的时候,我们是怎么用的呢?

  • Client端 Client端会引入Provider提供的SDK,注意SDK都是只提供接口interface, 不提供实现类
   @Reference(version = "1.0")
   // provider的接口Interface
    private HelloService helloService;

    public String doConsume(String word) {
        return helloService.sayHello(word);
    }
  • server端
@Service
public class HelloServiceImpl implements HelloService{

    public String sayHello(String word) {
        return "hello " + word;
    }
}

Client端虽然只是执行了Provider的interface代码,但是dubbo/feign 等rpc框架,在底层会将请求参数进行封装,序列化成对应的协议,再通过netty,进行tcp连接交互,调用Provider的机器,Provider机器收到tcp的数据请求,会反序列化出原来的数据,比如反序列化出来java对象,知道tcp的数据来源,是要去执行 Provider中某个类的某个方法,dubbo/feign框架,再通过反射去执行Provider对应的方法即可。

功能拆分

Client端

  • 注册
  • 负载均衡——找到Provider机器IP
  • tcp传输(netty4)——涉及沾包/拆包,序列化反序列化方式,读写心跳
  • 动态代理(jdk, javassit, cglib)——调用provider interface时,真正执行的类,构建tcp传输的参数
  • 序列化——json, ptotobuf, hession, protostuff,自定义序列化)——将java对象序列化,进行tcp交互
  • 反序列化(将tcp返回的的数据,反序列化为java对象)

Server端

  • 注册
  • tcp传输(netty4)——涉及沾包/拆包,序列化反序列化方式,读写心跳
  • 反射——真正执行provider对应的方法
  • 序列化——json, ptotobuf, hession, protostuff,自定义序列化)——将java对象序列化,进行tcp交互
  • 反序列化(将tcp返回的的数据,反序列化为java对象)