手撕RPC

作者: 起个名忒难 | 来源:发表于2019-03-27 20:44 被阅读0次

    RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP/IP或UDP,为通信程序之间携带信息数据。RPC将原来的本地调用转变为调用远端的服务器上的方法,给系统的处理能力和吞吐量带来了近似于无限制提升的可能。在OSI网络通信模型中,RPC跨域了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

    大白话一点,rpc对程序员朋友是透明的。你可以像调用本地方法一样调用远端方法,是两个JVM程序之间的信息交互。无论是本地方法还是远端方法,你直接用就可以了, 如果是远端方法剩下的交给RPC。

    • RPC作用:

      • 进程间通讯
      • 提供和本地调用一样的调用机制
      • 屏蔽掉远程调用的细节实现
    • 在spring中接口的调用是通过动态代理实现的,RPC自然也是。对JAVA来说调用方式有两种:

      • JDK动态代理
      • cglib代理

    尽管cglib代理的实现更为强大和高效,cglib可以不需要接口类,jdk动态代理必须要有接口类,但是在使用时还是首选jdk动态代理,因为接口类肯定会提供的。cglib的代码不易维护。

    • 调用流程


      调用流程.png
    • 调用步骤:

      • 服务方暴露服务,并提供调用地址
      • 服务消费方以调用本地方法的方式调用服务
      • 接收到请求后,将方法,参数组装成能够进行消息传输的消息体
      • 找到服务地址,并将消息发送到服务端
      • server收到消息后进行解码
      • 根据解码结果调用本地服务
      • 本地服务执行,并将服务执行结果发送给消费方
      • 消费方收到消息后子进行解码,得到执行的结果
    • 常用的分布式rpc:

      • dubbo , motan ,rpcx , grpc , thrift等

    下面手撕代码

    • 既然是调用远端服务,那么就必须在远端暴露一个服务,并提供调用地址,使用ServerSocker 来实现。
    server端暴露服务.png
    • 服务端暴露后,来写本地的动态代理方法,在本地调用时是通过动态代理来将请求转发到远端服务。
    image.png
    • 接口
    public interface HelloRpc {
        public String helloRpc(String args);
        String hellRpc(String arg1, String arg2);
    }
    
    • 实现类
    public class HelloRpcImpl implements HelloRpc {
        @Override
        public String helloRpc(String args) {
            return "HelloRPC : ---- " + args;
        }
        @Override
        public String hellRpc(String arg1, String arg2) {
            return "arg1 : " + arg1 + "args2:" + arg2;
        }
    }
    
    • 服务发布:
    public static void main(String[] args) throws IOException {
        HelloRpcImpl helloRpc = new HelloRpcImpl();
            RpcFrame.server(helloRpc , 80);
    }
    
    • 消费调用:
    public static void main(String[] args) {
        HelloRpc o = (HelloRpc) RpcFrame.helloRpc(HelloRpc.class, "127.0.0.1", 80);
        String hello = o.hellRpc("client !" , "verygood!");
        System.out.println(hello);
    }
    

    上面只是模拟rpc的实现方式,写的一段代码,市面上的rpc也不是这样搭建的。不过核心思想还是相同的。 但就dubbo而言,暴露的服务是要注册到zk上的,消费方如果需要某个服务,回去zk上查找,并在本地缓存。

    • rpc与队列对比
      • 既然是两个服务之间的交互,为什么不用队列?
      • 队列是异步化的,对于同步返回的需求是没法满足的
      • rpc既可以做同步,也可以做异步

    相关文章

      网友评论

          本文标题:手撕RPC

          本文链接:https://www.haomeiwen.com/subject/dijtbqtx.html