什么是RPC

什么是RPC

RPC的全称是Remote Procedure Call,即远程过程调用,是一种计算机通信协议。它允许程序在不同计算机之间进行通信和交互,就像本地调用一样。简单解读字面上的意思,远程是指要跨机器而非本机,所以需要用到网络编程才能实现。

为什么要用RPC

RPC的作用就是体现在这样两个方面:

  • 屏蔽远程调用跟本地调用的区别,让我们感觉就是调用项目内的方法;
  • 隐藏底层网络通信的复杂性,让我们更专注于业务逻辑。

RPC通信流程

发起调用请求的那一方叫做调用方,被调用的一方叫做服务提供方。

为了实现这个目标,就需要在RPC框架里面对整个通信细节进行封装

RPC是一个远程调用,是需要通过网络来传输数据,并且RPC常用于业务系统之间的数据交互,需要保证其可靠性,所以RPC一般默认采用TCP来传输。常用的HTTP协议也是建立在TCP之上的。

网络传输的数据必须是二进制数据,但调用方请求的出入参数都是对象。对象是肯定没法直接在网络中传输的,需要提前把它转成可传输的二进制,并且要求转换算法是可逆的,这个过程一般叫做“序列化”。

调用方持续地把请求参数序列化成二进制后,经过TCP传输给了服务提供方。服务提供方从TCP通道里面收到二进制数据。那如何知道一个请求的数据到哪里结束,是一个什么类型的请求呢?

答:把数据格式的约定内容叫做“协议”。大多数的协议会分成两部分,分别是数据头和消息体。数据头一般用于身份识别,包括协议标识、数据大小、请求类型、序列化类型等信息;消息体主要是请求的业务参数信息和扩展属性等。

根据协议格式,服务提供方就可以正确地从二进制数据中分割出不同的请求来,同时根据请求类型和序列化类型,把二进制的消息体逆向还原成请求对象。这个过程叫作“反序列化”。
在这里插入图片描述

服务提供方再根据反序列化出来的请求对象找到对应的实现类,完成真正的方法调用,然后把执行结果序列化后,回写到对应的TCP通道里面。调用方获取到应答的数据包后,再反序列化成应答对象,这样调用方就完成了一次RPC调用。

上述流程比较复杂,对研发人员需要掌握太多RPC底层细节,整体不太友好。

可以采用动态代理的技术简化上述流程,通过字节码增强对方法进行拦截增强,以便于增加需要的额外处理逻辑。

服务提供者给出业务接口声明,在调用方的程序里面,RPC框架根据调用的服务接口提前生成动态代理实现类,并通过依赖注入等技术注入到声明了该接口的相关业务逻辑里面。该代理实现类会拦截所有的方法调用,在提供的方法处理逻辑里面完成一整套的远程调用,并把远程调用结果返回给调用方,这样调用方在调用远程方法的时候就获得了像调用本地接口一样的体验。

整个调用流程如下:

image-20241020211325576

### RPC(远程过程调用)的作用 RPC是一种允许程序执行位于不同地址空间内的子程序的过程,而无需程序员显式编码处理底层网络细节的技术[^2]。这种机制使得应用程序之间的交互更加直观和简单,仿佛是在同一进程中调用函数一样。 #### 实现高效、透明的远程方法调用 通过使用RPC框架,开发人员可以在客户端发起请求并等待来自服务器端响应的结果,整个过程对于开发者来说几乎是透明化的。这不仅提高了编程效率还降低了复杂度,因为不需要关心数据传输的具体协议以及序列化/反序列化等问题。 ### 应用场景举例 #### Java中的典型应用场景 在Java环境中,RPC常用于构建微服务架构下的各个模块间通信解决方案。例如,在电商系统里订单管理服务可能会依赖库存查询服务来获取商品数量信息;此时就可以利用像Dubbo这样的高性能轻量级开源RPC框架完成跨进程的服务调用操作。 ```java // 客户端接口定义 public interface OrderService { String placeOrder(String productId); } // 服务提供方实现类 @Service("orderServiceImpl") public class OrderServiceImpl implements OrderService { @Autowired private StockQueryService stockQueryService; public String placeOrder(String productId){ int count = stockQueryService.getStockCount(productId); // 远程调用另一个服务 if (count > 0) { return "下单成功"; } else { return "库存不足"; } } } ``` #### Python中Frida库的应用案例 除了传统的Web或企业级应用外,RPC还可以应用于移动设备的安全测试领域。比如借助于Python Frida库,可以通过编写简单的脚本来拦截Android/iOS APP内部的方法调用,并对其进行修改或者监控,进而达到动态分析的目的[^4]。 ```python import frida import sys def on_message(message, data): print("[%s]" % message) jscode = """ rpc.exports = { showStack: function () { var stack = Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join("\\n"); send(stack); } }; """ process = frida.get_usb_device().attach('com.example.app') script = process.create_script(jscode) script.on('message', on_message) print('[*] Running CTF') script.load() sys.stdin.read() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不进大厂不改名1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值