概述

RPC(Remote Procedure Call),远程过程调用,是一个计算机通信协议,该协议允许运行一个进程调用另一个进程,而程序员无需额外为这个交互作用编程。

两个或者多个应用程序分布在不同的服务器上,他们之间的调用在客户端看来,就跟调用本地方法一样。

场景的RPC框架用阿里的dubbo、Google的gRPC,Apache的thrift、spring 的SpringCloud等。

调用流程:

clientsub是客户端本地调用的代理,ServerSub是服务端的代理。
流程解释:

  1. 服务消费端本地调用方式来调用远程服务。
  2. ClientSub接收到调用后,负责将方法,参数等,封装成能够进行网络传输的消息体。
  3. ClientSub将消息进行编码后发送到服务端。
  4. 服务端的ServerSub接收到消息后对消息进行解码。
  5. 找到服务器本地的对应服务进行调用,并把返回值返回给ServerSub。
  6. ServerSub对返回值进行编码并发送回消费端。
  7. clientSub对返回进行解码。
  8. 服务消费端得到调用结果。

RPC就是把2-7封装起来,然后消费端只需编码1的代码,和8的代码。

实战

这个demo仅仅使用了String类型的编解码器,也就是说只能进行String类型的数据传输。但也麻雀虽小,五脏俱全了。完成了基本的RPC通信。

代码量有点多,这里就直接上GitHub了,然后下面说说逻辑。

有三个包模块:

rpc-api:公共接口。
rpc-client:消费端。
rpc-provider:提供端。

使用方式:

服务端
  1. 服务端配置文件配置服务提供者。
    目录固定是类路径下的providerconfig目录下的配置文件,不包括子目录。


    服务端的配置文件只有2个项,分别是提供者的id,提供者的类全限定名称。
 public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, InterruptedException {//参数1位端口,参数2为业务线程池的大小。RpcServer rpcServer = new RpcServer(5858,100);//启动rpcServer.start();}

结果:

启动消费者:
  1. 配置消费者配置文件:固定下面目录下的配置文件。


    启动:
public class Testst {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {ClientBootStrap clientBootStrap = new ClientBootStrap();clientBootStrap.initClient();HelloService helloServiceConsumer = (HelloService) clientBootStrap.getConsumer("HelloServiceConsumer");System.out.println(helloServiceConsumer.sayHallo("Yehaocong"));HelloService helloService = (HelloService) clientBootStrap.getConsumer("HelloServiceConsumer1");System.out.println(helloService.sayHallo("Yehaoxian"));}
}

为了测试同一个客户端可以调用不同服务(ip/port不一样)提供者,我们启动两个服务端提供者,一个用5959端口,一个用5858端口。

然后测试:

远程调用成功。

大致原理

提供端:
  1. 服务启动时,解析配置文件,生成服务提供者,用一个map维护。这个代码在server.RpcServer#initProvider方法中。
  2. 当有消费端调用时,提供方NettyIO线程接收到数据后,转发给业务线程池调用。
  3. 业务线程池解析url,找到对应的提供者对象和对应的方法,执行调用,并返回结果给消费端。
    runable.ServiceRunnable#run方法。
消费端
  1. ClientBootStrap启动时,解析配置文件,生成消费者对象,用client维护,实际上生成的是用动态代理代理过的stub对象。bootstrap.ClientBootStrap#initClient方法。
  2. 想要用某个消费者调用远程,就使用ClientBootStrap.getConsumer方法并传入消费者id,获取消费者调用。
  3. 消费者调用实际上是执行stub.ClientStub#invoke方法。拼接url,进行url发送到服务端。阻塞等待结果返回,阻塞方式使用线程的wait和notify机制。
  4. 执行使用业务线程来执行,使用NettyIO线程专注IO。

消费端和服务端采用一个自定义编码器和Netty自带的LengthFieldBasedFrameDecoder解码器来解决粘包拆包问题。

测试代码:

结果:

GitHub地址:

https://github.com/YeHaocong1/rpc-demo

基于Netty的RPC框架相关推荐

  1. Java编写基于netty的RPC框架

    一 简单概念RPC: ( Remote Procedure Call),远程调用过程,是通过网络调用远程计算机的进程中某个方法,从而获取到想要的数据,过程如同调用本地的方法一样.阻塞IO :当阻塞I/ ...

  2. 手动实现一个基于netty的RPC框架(模拟dubble)

    轻量级RPC框架开发 内容安排: 1.掌握RPC原理 2.掌握nio操作 3.掌握netty简单的api 4.掌握自定义RPC框架 RPC原理学习 什么是RPC RPC(Remote Procedur ...

  3. Netty和RPC框架线程模型分析

    <Netty 进阶之路>.<分布式服务框架原理与实践>作者李林锋深入剖析Netty和RPC框架线程模型.李林锋已在 InfoQ 上开设 Netty 专题持续出稿,感兴趣的同学可 ...

  4. Netty 和 RPC 框架线程模型分析

    https://www.infoq.cn/article/9Ib3hbKSgQaALj02-90y 1. 背景 1.1 线程模型的重要性 对于 RPC 框架而言,影响其性能指标的主要有三个要素: I/ ...

  5. 基于Netty的RPC简易实现

    代码地址如下: http://www.demodashi.com/demo/13448.html 可以给你提供思路 也可以让你学到Netty相关的知识 当然,这只是一种实现方式 需求 看下图,其实这个 ...

  6. 基于Netty的RPC架构实战演练

    基于Netty的RPC架构实战演练 NIO netty服务端 netty客户端 netty线程模型源码分析(一) netty线程模型源码分析(二) netty5案例学习 netty学习之心跳 prot ...

  7. Courier:Dropbox 基于gRPC 的 RPC 框架开发过程

    Dropbox运行着数百个用不同语言编写的服务,每秒交换数百万次请求.Courier是我们面向服务的架构的核心,这是一个基于gRPC的远程过程调用(RPC)框架.在开发Courier时,我们学习了很多 ...

  8. 晁岳攀---基于go的 rpc框架实践

    晁岳攀:软件开发的老兵,Scala集合技术手册(简/繁版)的作者, 高性能的服务治理rpcx (Go)框架的开发者,先前在同方.Motorola.comcast从事软件开发工作,现在在微博平台研发部做 ...

  9. 基于RDMA的RPC框架(一) 环境搭建

    文章目录 一.简介 二.Ubuntu 14安装SoftRoce 2.1.编译内核 2.2.安装用户库 三.Ubuntu 18安装Soft Roce 引用 一.简介 二.Ubuntu 14安装SoftR ...

最新文章

  1. js url传值中文乱码完美解决(JAVA)
  2. spring注入----反射模式
  3. ⑨⑧借鉴成功者经验,吸取失败者教训
  4. 北京建委breaa.cn宕了
  5. 阿里P7面试官告诉你:3-5年以上的Android开发如何深入进阶?Android中高级开发必须掌握哪些?
  6. 8、非空约束(NOT NULL)
  7. 使用Storm进行可扩展的实时状态更新
  8. numpy细碎知识点
  9. python selenium 处理弹窗_转:python selenium 弹出框处理的实现
  10. 长江浪花~朵儿朵尔朵
  11. ubuntu 16.04 登录后黑屏
  12. pytorch 入门学习 MSE
  13. ACL2021最佳论文出炉,来自字节跳动
  14. HDU 5351 MZL's Border (规律,大数)
  15. 服务器主板型号详解,服务器电脑主板科普:各种接口介绍,如何选?
  16. Python3 - Dockerfile 最佳实践
  17. 1. 从键盘输入一系列字符(以回车符结束,字符的个数不超过 200 个),统计输入字符串中数字与非数字字符的个数,并将计数结果输出。
  18. HTPP的请求方式有哪些?
  19. 田野调查手记·浮山篇(九)
  20. About 9.18 This Week

热门文章

  1. 安卓学习笔记23:常用控件 - 网格视图与图像切换器
  2. 大数据学习笔记09:MapReduce概述
  3. 复数基础——虚数和复数_5
  4. 中南大学计算机院转专业要求,机电工程学院2018级本科学生转专业的实施细则...
  5. 计算机主机硬件详细介绍,计算机系统的硬件和系统软件详细介绍
  6. 从汇编代码的角度观察switch与if...else,乘除与移位的差别
  7. MySQL事件的使用
  8. 递归函数合式分解python_零基础学python-18.2 递归函数与分解递归函数的执行步骤
  9. OpenGL ES 简单教程
  10. 如履薄冰 —— Redis懒惰删除的巨大牺牲