RPC(3)

75 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第28天,点击查看活动详情

RPC 框架代码分析之网络传输模块

Socket

客户端流程分析

客户端比较简单,重点在于通过服务发现类serviceDiscovery拿到服务端地址,之后的过程就跟正常的socket差不多

服务端流程分析

服务端逻辑较客户端会难一些。在启动服务端时,就会将方法类注册到服务端rpcServiceConfig,通过点开源码发现是在ZkServiceProviderImpl这个类中的publishService方法进行注册,

这里有个疑问:因为我clone的项目只有一个方法类,要是有很多方法类,都得手动的一个一个去添加到配置类中去吗?

然后就可以启动服务端流程了,服务端流程如下

  1. 通过String host = InetAddress.getLocalHost().getHostAddress();拿到服务端IP地址
  2. Ip地址与端口号形成套接字,将该地址应该是注册到哪里去,等到后面分析Zookeeper时再说吧
  3. 只要连接上了客户端,就从线程池中开启一个线程执行任务
  4. 先从请求中拿到相应信息,再封装一个输出流
  5. 通过rpcRequestHandler.handle(rpcRequest)就可以拿到客户端请求的方法的返回结果
  6. 把该返回结果写入输出流中,封装为Response进行返回即可

以上就是使用Socket进行网络传输的思路

接下来是使用Netty进行网络传输,原理差不多,代码实现大有差别

Netty

客户端

当然的,先从客户端开始分析

客户端有2个方法,

  • doConnect() :用于连接服务端(目标方法所在的服务器)并返回对应的 Channel。当我们知道了服务端的地址之后,我们就可以通过 NettyClient 成功连接服务端了。(有了 Channel 之后就能发送数据到服务端了)
  • sendRpcRequest() : 用于传输 rpc 请求(RpcRequest) 到服务端。
  1. 这里用CompletableFuture来代替Runnable+Thread和Callable+Thread的原因如下

    • Runnable+Thread虽然提供了多线程的能力但是没有返回值。
    • Callable+Thread的方法提供多线程和返回值的能力但是在获取返回值的时候会阻塞主线程。