基于Netty的RPC框架
概述
RPC(Remote Procedure Call),远程过程调用,是一个计算机通信协议,该协议允许运行一个进程调用另一个进程,而程序员无需额外为这个交互作用编程。
两个或者多个应用程序分布在不同的服务器上,他们之间的调用在客户端看来,就跟调用本地方法一样。
场景的RPC框架用阿里的dubbo、Google的gRPC,Apache的thrift、spring 的SpringCloud等。
调用流程:
clientsub是客户端本地调用的代理,ServerSub是服务端的代理。
流程解释:
- 服务消费端本地调用方式来调用远程服务。
- ClientSub接收到调用后,负责将方法,参数等,封装成能够进行网络传输的消息体。
- ClientSub将消息进行编码后发送到服务端。
- 服务端的ServerSub接收到消息后对消息进行解码。
- 找到服务器本地的对应服务进行调用,并把返回值返回给ServerSub。
- ServerSub对返回值进行编码并发送回消费端。
- clientSub对返回进行解码。
- 服务消费端得到调用结果。
RPC就是把2-7封装起来,然后消费端只需编码1的代码,和8的代码。
实战
这个demo仅仅使用了String类型的编解码器,也就是说只能进行String类型的数据传输。但也麻雀虽小,五脏俱全了。完成了基本的RPC通信。
代码量有点多,这里就直接上GitHub了,然后下面说说逻辑。
有三个包模块:
rpc-api:公共接口。
rpc-client:消费端。
rpc-provider:提供端。
使用方式:
服务端
- 服务端配置文件配置服务提供者。
目录固定是类路径下的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();}
结果:
启动消费者:
- 配置消费者配置文件:固定下面目录下的配置文件。
启动:
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端口。
然后测试:
远程调用成功。
大致原理
提供端:
- 服务启动时,解析配置文件,生成服务提供者,用一个map维护。这个代码在server.RpcServer#initProvider方法中。
- 当有消费端调用时,提供方NettyIO线程接收到数据后,转发给业务线程池调用。
- 业务线程池解析url,找到对应的提供者对象和对应的方法,执行调用,并返回结果给消费端。
runable.ServiceRunnable#run方法。
消费端
- ClientBootStrap启动时,解析配置文件,生成消费者对象,用client维护,实际上生成的是用动态代理代理过的stub对象。bootstrap.ClientBootStrap#initClient方法。
- 想要用某个消费者调用远程,就使用ClientBootStrap.getConsumer方法并传入消费者id,获取消费者调用。
- 消费者调用实际上是执行stub.ClientStub#invoke方法。拼接url,进行url发送到服务端。阻塞等待结果返回,阻塞方式使用线程的wait和notify机制。
- 执行使用业务线程来执行,使用NettyIO线程专注IO。
消费端和服务端采用一个自定义编码器和Netty自带的LengthFieldBasedFrameDecoder解码器来解决粘包拆包问题。
测试代码:
结果:
GitHub地址:
https://github.com/YeHaocong1/rpc-demo
基于Netty的RPC框架相关推荐
- Java编写基于netty的RPC框架
一 简单概念RPC: ( Remote Procedure Call),远程调用过程,是通过网络调用远程计算机的进程中某个方法,从而获取到想要的数据,过程如同调用本地的方法一样.阻塞IO :当阻塞I/ ...
- 手动实现一个基于netty的RPC框架(模拟dubble)
轻量级RPC框架开发 内容安排: 1.掌握RPC原理 2.掌握nio操作 3.掌握netty简单的api 4.掌握自定义RPC框架 RPC原理学习 什么是RPC RPC(Remote Procedur ...
- Netty和RPC框架线程模型分析
<Netty 进阶之路>.<分布式服务框架原理与实践>作者李林锋深入剖析Netty和RPC框架线程模型.李林锋已在 InfoQ 上开设 Netty 专题持续出稿,感兴趣的同学可 ...
- Netty 和 RPC 框架线程模型分析
https://www.infoq.cn/article/9Ib3hbKSgQaALj02-90y 1. 背景 1.1 线程模型的重要性 对于 RPC 框架而言,影响其性能指标的主要有三个要素: I/ ...
- 基于Netty的RPC简易实现
代码地址如下: http://www.demodashi.com/demo/13448.html 可以给你提供思路 也可以让你学到Netty相关的知识 当然,这只是一种实现方式 需求 看下图,其实这个 ...
- 基于Netty的RPC架构实战演练
基于Netty的RPC架构实战演练 NIO netty服务端 netty客户端 netty线程模型源码分析(一) netty线程模型源码分析(二) netty5案例学习 netty学习之心跳 prot ...
- Courier:Dropbox 基于gRPC 的 RPC 框架开发过程
Dropbox运行着数百个用不同语言编写的服务,每秒交换数百万次请求.Courier是我们面向服务的架构的核心,这是一个基于gRPC的远程过程调用(RPC)框架.在开发Courier时,我们学习了很多 ...
- 晁岳攀---基于go的 rpc框架实践
晁岳攀:软件开发的老兵,Scala集合技术手册(简/繁版)的作者, 高性能的服务治理rpcx (Go)框架的开发者,先前在同方.Motorola.comcast从事软件开发工作,现在在微博平台研发部做 ...
- 基于RDMA的RPC框架(一) 环境搭建
文章目录 一.简介 二.Ubuntu 14安装SoftRoce 2.1.编译内核 2.2.安装用户库 三.Ubuntu 18安装Soft Roce 引用 一.简介 二.Ubuntu 14安装SoftR ...
最新文章
- js url传值中文乱码完美解决(JAVA)
- spring注入----反射模式
- ⑨⑧借鉴成功者经验,吸取失败者教训
- 北京建委breaa.cn宕了
- 阿里P7面试官告诉你:3-5年以上的Android开发如何深入进阶?Android中高级开发必须掌握哪些?
- 8、非空约束(NOT NULL)
- 使用Storm进行可扩展的实时状态更新
- numpy细碎知识点
- python selenium 处理弹窗_转:python selenium 弹出框处理的实现
- 长江浪花~朵儿朵尔朵
- ubuntu 16.04 登录后黑屏
- pytorch 入门学习 MSE
- ACL2021最佳论文出炉,来自字节跳动
- HDU 5351 MZL's Border (规律,大数)
- 服务器主板型号详解,服务器电脑主板科普:各种接口介绍,如何选?
- Python3 - Dockerfile 最佳实践
- 1. 从键盘输入一系列字符(以回车符结束,字符的个数不超过 200 个),统计输入字符串中数字与非数字字符的个数,并将计数结果输出。
- HTPP的请求方式有哪些?
- 田野调查手记·浮山篇(九)
- About 9.18 This Week
热门文章
- 安卓学习笔记23:常用控件 - 网格视图与图像切换器
- 大数据学习笔记09:MapReduce概述
- 复数基础——虚数和复数_5
- 中南大学计算机院转专业要求,机电工程学院2018级本科学生转专业的实施细则...
- 计算机主机硬件详细介绍,计算机系统的硬件和系统软件详细介绍
- 从汇编代码的角度观察switch与if...else,乘除与移位的差别
- MySQL事件的使用
- 递归函数合式分解python_零基础学python-18.2 递归函数与分解递归函数的执行步骤
- OpenGL ES 简单教程
- 如履薄冰 —— Redis懒惰删除的巨大牺牲