rpc调用过程原理分析以及Dubbo、Feign调用过程

article/2025/10/4 0:51:44

RPC简介

RPC是远程过程调用(Remote Procedure Call)的缩写形式。

RPC调用流程图

 

客户端方法:服务调用方所调用的接口

客户端代理:将接口封装成代理对象,并序列化请求参数、反序列化响应结果,使用远程传输协议调用服务端,(例如:Socket、Netty、RMI、HTTP等)。

远程网络调用:采用远程传输协议进行通信实现数据的传输。

服务端代理:服务端收到远程请求后,将二进制的数据反序列化为请求对象,然后调用本地接口返回响应数据并序列化结果发送出去。

服务端方法:服务提供者具体的实现,也就是最终请求的方法。

 

RPC的简单实现

接下来通过一个简单的demo来分析RPC调用过程

源码git地址:https://github.com/xxiangzh/x-rpc

项目结构,consumer为服务调用者,即客户端;provider为服务提供者,即服务端。

接口调用过程

代码详情

用户接口(客户端和服务端相同,复制过去即可)

public interface UserService {String getUserNameById(Long userId);
}

RPC通信参数(客户端和服务端相同,复制过去即可)

@Data
@NoArgsConstructor
@AllArgsConstructor
public class RpcRequest implements Serializable {private static final long serialVersionUID = 1L;private String methodName;private Long parameter;}

用户接口实现类(客户端通过远程RPC最终调用的是这个接口)

public class UserServiceImpl implements UserService {public String getUserNameById(Long userId) {return userId > 0 ? "向振华" : "无名";}
}

服务提供者RPC通信类,采用socket通信

public class RpcHandler {public void run() throws Exception {ServerSocket serverSocket = new ServerSocket(8081);while (true) {Socket socket = serverSocket.accept();// 将请求体反序列化ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());Object object = objectInputStream.readObject();// 服务调用Object result = null;if (object instanceof RpcRequest) {RpcRequest rpcRequest = (RpcRequest) object;if ("getUserNameById".equals(rpcRequest.getMethodName())) {UserService userService = new UserServiceImpl();result = userService.getUserNameById(rpcRequest.getParameter());} else {throw new RuntimeException("method not found");}}// 结果返回ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());objectOutputStream.writeObject(result);}// TODO socket.close(); serverSocket.close();}
}

然后启动服务提供者

public class ProviderTest {public static void main(String[] args) throws Exception {new RpcHandler().run();}
}

服务调用者,用户接口的实现,这里是通过RPC方式调用

public class RpcUserServiceImpl implements UserService {public String getUserNameById(Long userId) {try {Socket socket = new Socket("127.0.0.1", 8081);// 将请求体序列化并发给服务提供方RpcRequest rpcRequest = new RpcRequest("getUserNameById", userId);ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());objectOutputStream.writeObject(rpcRequest);// 将响应体反序列化ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());Object response = objectInputStream.readObject();// 返回结果return (String) response;} catch (Exception e) {return null;}// TODO socket.close();}
}

服务调用者测试类

public class ConsumerTest {public static void main(String[] args) {UserService userService = new RpcUserServiceImpl();System.out.println(userService.getUserNameById(1L));System.out.println(userService.getUserNameById(-1L));}
}

启动服务端,然后再运行客户端测试类,即可得到结果。通过这个demo可以了解到RPC远程调用的大致流程,但是真正的RPC框架远不止这么简单。

真正的RPC会对接口代理、对请求信息统一封装通过反射实例化,通过注册中心维护服务器实例,通过负载均衡提供服务的灵活性和可用性,另外还有监控、拦截器、日志等等。

 

Dubbo

版本:2.7

Dubbo(读音[ˈdʌbəʊ])是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成。

Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

接下来看看Dubbo服务调用过程

Dubbo整体设计

图片来源于:https://dubbo.apache.org/zh/docs/v2.7/dev/design/ 

各层说明 

  • config 配置层:对外配置接口,以 ServiceConfigReferenceConfig 为中心,可以直接初始化配置类,也可以通过 spring 解析配置生成配置类
  • proxy 服务代理层:服务接口透明代理,生成服务的客户端 Stub 和服务器端 Skeleton, 以 ServiceProxy 为中心,扩展接口为 ProxyFactory
  • registry 注册中心层:封装服务地址的注册与发现,以服务 URL 为中心,扩展接口为 RegistryFactoryRegistryRegistryService
  • cluster 路由层:封装多个提供者的路由及负载均衡,并桥接注册中心,以 Invoker 为中心,扩展接口为 ClusterDirectoryRouterLoadBalance
  • monitor 监控层:RPC 调用次数和调用时间监控,以 Statistics 为中心,扩展接口为 MonitorFactoryMonitorMonitorService
  • protocol 远程调用层:封装 RPC 调用,以 InvocationResult 为中心,扩展接口为 ProtocolInvokerExporter
  • exchange 信息交换层:封装请求响应模式,同步转异步,以 RequestResponse 为中心,扩展接口为 ExchangerExchangeChannelExchangeClientExchangeServer
  • transport 网络传输层:抽象 mina 和 netty 为统一接口,以 Message 为中心,扩展接口为 ChannelTransporterClientServerCodec
  • serialize 数据序列化层:可复用的一些工具,扩展接口为 SerializationObjectInputObjectOutputThreadPool

整个调用链如下图所示

Dubbo调用链

整个过程看起来负责多了,但是核心流程并没变,只是加了很多高可用、高性能的扩展。

客户端通过ProxyFactory代理工厂创建代理类,然后进入过滤器链路,然后构建Invoker对象,通过注册中心发现服务,通过负载均衡策略选择远程服务提供者,发起远程调用,然后通过远程传输协议将数据发送到服务端,服务端接收到请求后对数据进行解析、序列化,从线程池获取服务线程执行,再进入服务提供者的过滤器链路,然后端通过ProxyFactory代理工厂创建代理类构建Invoker对象,执行本地方并返回结果。

 

Spring Cloud Feign

Feign是一个声明式的REST客户端,它的目的就是让REST调用更加简单。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。

Feign远程调用的基本流程

图来源于:https://www.cnblogs.com/crazymakercircle/p/11965726.html

Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的 Request 请求。通过Feign以及JAVA的动态代理机制,使得Java 开发人员,可以不用通过HTTP框架去封装HTTP请求报文的方式,完成远程服务的HTTP调用。

Feign默认采用HttpURLConnection进行远程通信,新能比较差,可以改为OKHttp或者Netty等。


http://chatgpt.dhexx.cn/article/jPB0A7t8.shtml

相关文章

SpringBoot+RabbitMQ 实现 RPC 调用

说到 RPC(Remote Procedure Call Protocol 远程过程调用协议),小伙伴们脑海里蹦出的估计都是 RESTful API、Dubbo、WebService、Java RMI、CORBA 等。 其实,RabbitMQ 也给我们提供了 RPC 功能,并且使用起来很简单。 …

消息中间件RabbitMQ(五)——实现RPC调用

文章目录 1. RPC2. 实现原理3. 代码实现3.1 客户端实现3.2 服务端实现3.3 测试 4. 小结 1. RPC 对于微服务开发者,对于 RPC(Remote Procedure Call Protocol 远程过程调用协议)并不会陌生吧, RESTful API、Dubbo、WebService等都…

springcloud 远程rpc调用接口

springcloud 如果想要从注册中心中调用已经注册的接口,需要用如下方法。 我们现在已经将一个微服务注册到了注册中心。端口是8083的那个 并且里面有个member的RequestMapping 首先,创建一个微服务,将需要的依赖放入pom.xml和配置好apppli…

浅谈RPC调用过程

RPC(Remote Procedure Call) - 远程过程调用,是一个计算机通信协议,它允许运行于一台计算机的程序调用另一台计算机的子程序,而无需额外地为这个交互作用编程。RPC主要应用在分布式系统架构中不同的系统之间的远程通信和相互调用。 举个例子…

远程RPC调用用于js逆向

这里只是记录于学习,资源来自于大佬的github,有十分详细的介绍,我仅仅拿来一用。https://github.com/jxhczhl/JsRpc。(注RPC在某些网站会被检测到) 在右侧下载适合自己系统的exe文件,双击打开 练习对象是某…

使用 webservice 实现 RPC 调用

WebService 介绍 Web service 是一个平台独立的,低耦合的 web 的应用程序用于开发分布式的互操作的应用程序。Web Service 技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。 SO…

RPC调用链通信方法

RPC调用链可以将远程过程调用变成一个有效的堆栈。 当我们编写应用程序时,我们中的许多人认为REST是服务间通信的一个通用标准。然而,还有许多其他形式的通信,RPC就是其中之一。值得注意的是,通信方式的选择取决于许多因素&#…

使用Dubbo实现简单的RPC调用(Spring配置文件版)

更多文章和资源欢迎访问:SuperCoder Blog 文章目录 更多文章和资源欢迎访问:[SuperCoder Blog](https://supercoder.com.cn)前言一、Dubbo架构二、安装zookeeper三、代码实战1. 创建服务提供方2. 创建服务消费方 四、服务调用 前言 Dubbo是阿里巴巴公司…

用一个简单的函数来理一下RPC调用过程

1.什么是RPC RPC(Remote Procedure Call)远程过程调度,简单的理解就是一个节点请求另一个节点的提供的服务。 2.远程调用要面临的三个问题。 (1)Call ID映射。本地调用中,函数体是直接通过函数指针来指定…

Dubbo的RPC调用流程

首先在客户端启动时会从注册中心拉去和订阅对应的服务列表,Cluster会把拉取到的服务列表聚合成一个cluster,每次RPC调用前会通过Directory#list获取providers地址(已经生成好的invoker列表),获取这些服务列表给后续路由和负载均衡使用,框架内…

RPC 调用原理

RPC调用原理 RPC原理 RPC(Remote Procedure Call)即远程过程调用,允许一台计算机调用另一台计算机上的程序得到结果,而代码中不需要做额外的编程,就像在本地调用一样。分布式的应用可以借助RPC来完成服务之间的调用。 RPC框架原理 在RPC框架…

RPC调用完整流程

RPC调用完整流程:   调用方持续把请求参数对象序列化成二进制数据,经过 TCP 传输到服务提供方;服务提供方从 TCP 通道里面接收到二进制数据;根据 RPC 协议,服务提供方将二进制数据分割出不同的请求数据,经…

RPC调用

1.RPC调用、本地调用和HTTP调用 网络调用一般是基于HTTP协议进行调用,RPC是使用TCP或者UDP协议进行调用,效率上回更好; 常用的RPC框架有Thrift、GRPC等; 2.RPC的调用时序图 1)调用方调用Proxy请求服务,并…

简单实现rpc调用

rpc调用 代码地址 查看代码 rpc称远程调用过程,在rpc调用过程中需要解决的几个问题。 代理协议序列化 技术选型 协议,我们使用java的socket编程套接字代理,使用java的动态代理序列化,使用java的原生的序列化。 rpc衍生出来…

Go rpc调用

RPC原理图 客户端Stub: 客户端存根服务端Stub: 服务端存根 RPC技术架构 服务端:server.go package mainimport ("math""net""net/http""net/rpc" )type MathUtil struct { }// 该方法向外暴露:提供计算圆形面…

rpc调用 java_RPC调用的简单实现

RPC调用流程 流程描述: 1.服务调用者发送请求(interface#method#args) 2.客户端进行StringEncode编码 3.数据写到服务提供者 4.服务提供者接受请求 5.将接收的包进行StringDecode解码 6.服务提供方调用对应api 7.服务提供方响应方法调用结果 8.服务提供方将结果集进行StringEn…

RPC调用和HTTP调用的区别

一.远程调用方式 无论是微服务还是分布式服务(都是SOA,都是面向服务编程),都面临着服务间的远程调用。那么服务间的远程调用方式有哪些呢? 常见的远程调用方式有以下几种: RPC:Remote Produce…

RPC远程调用通俗理解

先从一个案例来讲RPC 为了提升饭店的服务能力,饭店从一开始只有一个负责所有事情的厨师发展成有厨师、切菜师、备菜师等多个角色。在饭店只有一个厨师的时候,厨师想要做出一道美味的番茄炒蛋的时候,他需要自己洗番茄、切番茄、打鸡蛋、炒菜。…

RPC通信基本原理 -- 浅析RPC远程过程调用基本原理

一、RPC基本概念 1.1、RPC简介 RPC 的全称是 Remote Procedure Call是一种进程间通信方式。RPC只是一个概念 而不是具体的协议或框架。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远…

RPC服务调用

RPC服务调用 一、RPC实现原理深入分析1、RPC的定义(1)RPC作用(2)RPC核心组成(3)RPC调用方式 二、精简版RPC调用代码实现1、场景2、接口设计3、序列化协议 最近在做调用系统相关的服务,采用主从的…