一、背景
前段时间了解了泛化调用这个玩意儿,又想到自己之前写过一个RPC框架(参考《手写一个RPC框架》),于是便想小试牛刀。
二、泛化调用简介
什么是泛化调用
泛化调用就是在不依赖服务方接口jar包的情况下进行调用,包括对调用方法的泛化、参数的泛化和返回值的泛化。
泛化调用的使用场景
常规的PRC调用都是客户端依赖服务端提供的接口jar包,然后利用动态代理技术,像调用本地方法一样调用远程方法,但是有些场景下客户端无法依赖jar包,也要调用远程方法,这时就需要用到泛化调用了。
常规的使用场景包括:
-
网关,如果服务内部调用使用RPC协议,对外暴露HTTP接口,这时就需要在网关做协议转换(HTTP转RPC协议),但是网关不可能依赖所有接口的jar包,只能采用泛化调用。
-
测试平台
实现方案
实现方案有两种:
- 第一种是基于Java Bean的泛化调用,例如dubbo的泛化调用会将参数转换成JavaBeanDescriptor,代码可以参考GenericFilter。
- 第二种是基于序列化中间体的泛化调用,如sofa-rpc,使用了sofa-hessian序列化框架,sofa-hessian是在hessian序列化框架基础上进行二次开发的,抽象出了序列化中间体,如GenericObject、GenericMap、GenericArray等。
三、开发实现
3.1 类图
客户端

服务注册和发现

3.2 数据传输过程

3.3 客户端实现
首先定义一个泛化调用接口GenericService
java
复制代码
public interface GenericService { /** * 泛化调用 * @param methodName * @param parameterTypeNames * @param args * @return */ Object $invoke(String methodName, String[] parameterTypeNames, Object[] args); }
注意: 这里参数类型parameterTypeNames用的是参数类型名称数组而不是Class数组,是因为泛化调用客户端可能不存在对应的类。
默认实现类DefaultGenericService
java
复制代码
/** * @Author: Ship * @Description: * @Date: Created in 2023/6/15 */ public class DefaultGenericService implements GenericService { private MethodInvoker methodInvoker; priva

本文介绍了泛化调用的概念,即在没有服务方接口jar包的情况下进行远程调用。文章详细阐述了泛化调用的使用场景,如网关协议转换和测试平台,并对比了两种实现方案:基于JavaBean和基于序列化中间体。接着,展示了自定义RPC框架中泛化调用的客户端和服务端实现,包括类图、数据传输过程以及关键类的代码实现。最后,进行了功能测试和性能压测,结果显示QPS达到3600多,证明了实现的有效性。
最低0.47元/天 解锁文章
1320

被折叠的 条评论
为什么被折叠?



