一文了解RPC框架原理
点击上方“开源Linux”,选择“设为星标”
回复“学习”获取独家整理的学习资料!
1.RPC框架的概念
RPC(Remote Procedure Call)–远程过程调用,通过网络通信调用不同的服务,共同支撑一个软件系统,微服务实现的基石技术。使用RPC可以解耦系统,方便维护,同时增加系统处理请求的能力。
上面是一个简单的软件系统结构,我们拆分出来用户系统和订单系统做为服务存在,让不同的站点去调用。
只需要引入各个服务的接口包,在代码中调用RPC服务就跟调用本地方法一样,我刚接触到这种调用方式的时候颇为惊奇,我明明调用的就是java语言方法啊(以java为例,现在RPC框架一般都支持多语言),怎么就调用了远程的服务了呢??
2.RPC框架的原理解析
2.1 流程纵览
如上图所示,我将一个RPC调用流程概括为上图中5个流程,左边3个为客户端流程,右边两个为服务端流程。下面就各流程进行解析
2.2 客户端调用
服务调用方在调用服务时,一般进行相关初始化,通过配置文件/配置中心 获取服务端地址 用户调用:
// 用户服务接口
public interface UserService {
public User genericUser(Integer id,String name,Long phone);
}
//调用方
//服务初始化
KRPC.init("D:\\krpc\\service\\demo\\conf\\client.xml");
UserService service = ProxyFactory.create(UserService.class, "demo","demoService");
User user = service.genericUser(1, "yasin", 1888888888L);
一开始接触RPC调用方法肯定就有疑惑,它不是一个接口吗,直接调用应该没啥效果啊,我也没有引入实现包。
带着这个疑惑,我们就进入下一个知识点,动态代理
2.3动态代理
动态代理这东西意如其名,它代理你帮你做事情。上面我们不说直接调用一个接口中的方法,并且没有用该接口的实现类调用,那么方法是怎么生效的呢?
可以看到这个用户服务这个service是由ProxyFactory代理工程创造的,在该ProxyFactory#create()方法中就跟一个代理处理器绑定在一起了
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//构造请求request
Request request = new Request();
....
return RequestHandler.request(serviceName, request,returnClass);
}
这个类实现了InvocationHandler接口(JDK提供的动态代理技术),每次去调用接口方法,最终都交由该handler进行处理。这个环节一般会获取方法的一些信息,例如方法名,方法参数类型,方法参数值,返回对象类型。
同时这个环节会提供序列化功能,一般的RPC网络传输使用TCP(哪怕使用HTTP)传输,这里也要将这些参数进行封装成我们定义的数据接口进行传输。
2.4网络传输
我们通过将方法参数进行处理后,就要使用发起网络请求,使用tcp传输的就利用socket通信进行传输,这一块我开源项目中使用的同步堵塞的方案进行请求,也可以使用一些非堵塞方案进行请求,效率会更高一些。
2.5服务端数据接受
这一块使用netty,可以快速一个高性能、高可靠的一个服务端。
public class ServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buf = (ByteBuf)msg;
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);
byte[] responseBytes = RequestHandler.handler(bytes);
ByteBuf resbuf = ctx.alloc().buffer(responseBytes.length);
resbuf.writeBytes(responseBytes);
ctx.writeAndFlush(resbuf);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
上面代码是我项目中使用的服务端代码。关于netty网上学习的资料很多,这里也只是宏观的讲解RPC原理,就不展开。
2.6真实调用
服务端获取客户端请求的数据后, 调用请求中的方法,方法参数值,通过反射调用真实的方法,获取其返回值,将其序列化封装,通过netty进行数据返回,客户端在接受数据并解析,这就完成了一次rpc请求调用的全过程。
method = clazz.getMethod(request.getMethodName(),requestParamTypes);
method.setAccessible(true);
result = method.invoke(service, requestParmsValues)
上面代码片段为通过反射调用真实方法
2.7 服务端的动态加载
通过2.2到2.6的说明,一次RPC请求过程大致如此,但是一个RPC框架会有很多细节需要处理。
其实在一次请求调用前,服务端肯定要先启动。
服务端作为一个容器,跟我们熟知的tomcat一样,它可以动态的加载任何项目。所以在服务端启动的时候,必须要进行一个动态加载的过程。在KRPC中,我使用了URLClassLoader动态加载一个指定路径的jar包,任何业务服务的实现所依赖的jar包都可以放入该路径中。
3.总结
一个RPC框架大致需要动态代理、序列化、网络请求、网络请求接受(netty实现)、动态加载、反射这些知识点。现在开源及各公司自己造的RPC框架层出不穷,唯有掌握原理是一劳永逸的。掌握原理最好的方法莫不是阅读源码,自己动手写是最快的。
作者:_Yasin
出处:http://002ii.cn/rxIivD
- End -
关注「开源Linux」加星标,提升IT技能
一文了解RPC框架原理的更多相关文章
- RPC 框架原理详解
首先了解什么叫RPC,为什么要RPC,RPC是指远程过程调用?也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网 ...
- RPC框架原理与实现
了解一个框架最好的思路就是寻找一个该类型麻雀虽小五脏俱全的开源项目,不负所期,轻量级分布式 RPC 框架 RPC,全称 Remote Procedure Call(远程过程调用),即调用远程计算机上的 ...
- RPC框架原理简述:从实现一个简易RPCFramework说起(转)
摘要: 本文阐述了RPC框架与远程调用的产生背景,介绍了RPC的基本概念和使用背景,之后手动实现了简易的RPC框架并佐以实例进行演示,以便让各位看官对RPC有一个感性.清晰和完整的认识,最后讨论了RP ...
- RPC框架原理剖析(含实例)(转)
转自:http://blog.csdn.net/rulon147/article/details/53814589 一.什么是RPC RPC(Remote Procedure Call Protoco ...
- 【Hadoop】Hadoop 中 RPC框架原理、代码示例
0.内容 1.hadoop中的RPC框架封装思想 2.Hadoop RPC 实现方法 3.服务调用动态转发和负载均衡的实现思考 4.协议代码: package com.ares.hadoop.rpc; ...
- 微服务理论之三:RPC框架原理
RPC调用是面向服务架构场景下进行服务间调用的常用组件,一个完整的RPC调用的流程如图1所示: 图1 RPC调用流程 为了方便RPC调用者和服务者的开发,开发者们开发了很多RPC框架.比较有名的RPC ...
- 一篇文章了解RPC框架原理
1.RPC框架的概念 RPC(Remote Procedure Call)–远程过程调用,通过网络通信调用不同的服务,共同支撑一个软件系统,微服务实现的基石技术.使用RPC可以解耦系统,方便维护,同时 ...
- 一个高性能RPC框架原理剖析
业务与底层网络通信分离 Server大部分主要分为两层: 网络接收层:负责监听端口,负责收包,编码,解码工作,负责将响应包回传给客户端. 业务处理层:负责接收网络接收层完整的包,如果是RPCserve ...
- 五分钟快速掌握RPC原理及实现
随着公司规模的不断扩大,以及业务量的激增,单体应用逐步演化为服务/微服务的架构模式, 服务之间的调用大多采用rpc的方式调用,或者消息队列的方式进行解耦.几乎每个大厂都会创建自己的rpc框架,或者基于 ...
随机推荐
- @RequestMapping与@Autowired的作用
@RequestMapping RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上.用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径. @Autowired @ ...
- jsp报错问题之“使用jstl的c标签choose报错Illegal text inside "c:choose" tag问题”
一.报错 [bessky_it][ERROR][2022-03-25 17:19:07] | PLATFORM | ):[c]鍜孾/com.bessky.pss.portal/purchase/sam ...
- 企业流程再造(BPR)--系统重构
企业流程再造(BPR) 企业流程:指生产或服务过程中一连串活动的工作流程 企业流程再造:对企业流程所进行的根本性的在思考和彻底的再设计,以使企业的速度,质量,服务和成本等关键业绩指标获得根本性的改善
- 控制算法的划分(自适应控制、预测控制、模糊控制等,PID等;蚁群算法、神经网络,还有机器学习、人工智能中的很多方法)
一般来说,控制器的设计,分为控制框架的选取,跟参数的优化.自适应控制.预测控制.模糊控制等,跟PID一样,是控制算法(我习惯称为控制框架). 而粒子群.遗传算法(类似的还有蚁群算法.神经网络,还有机器 ...
- 8 个有用的 HTML5 标签
作为一个 web 前端开发者,在制作页面的时候你会从一大堆不同的标签中选择合适的标签来完成相应的功能.有些 HTML5 标签广为流传,例如 <article> <header> ...
- MySQL 中 SQL语句大全(详细)
sql语句总结 总结内容 1. 基本概念 2. SQL列的常用类型 3. DDL简单操作 3.1 数据库操作 3.2 表操作 4. DML操作 4.1 修改操作(UPDATE SET) 4.2 插入操 ...
- ajax自己封装
function paramsSeralize(obj){ if(!obj || typeof !== 'object') return obj; let res = ''; for (const k ...
- BootstrapBlazor 使用模板创建项目
原文连接:https://www.cnblogs.com/ysmc/p/16101157.html BootstrapBlazor 官网地址:https://www.blazor.zone Boots ...
- MySQL高级以及锁机制
MySQL高级 推荐阅读: 锁:https://www.cnblogs.com/zwtblog/tag/锁/ 数据库:https://www.cnblogs.com/zwtblog/tag/数据库/ ...
- Docker引擎核心组件
Docker Engine(Docker引擎)是Docker的核心部分,使用的是客户端-服务器(C/S)架构模式,其主要组成部分如下图所示. 从上图中可以看出,Docker Engine中包含了三个核 ...