手动实现简易版RPC(三)

news/2024/9/24 5:27:30/

手动实现简易版RPC(三)

往期内容

  • 手动实现简易版RPC(一):RPC简介及系统架构

  • 手动实现简易版RPC(二):简单RPC框架实现

前言

接上两篇博客我们实现了最简易RPC框架,接下来的几期重点在简易版的rpc框架上继续深耕。本文主要介绍简易版RPC 中mock假数据相关的内容。


RPC(Remote Procedure Call)框架的核心在于通过网络实现远程过程调用,使得调用远程服务如同调用本地服务一样方便。但是在实际开发中,可能在调用远程过程中不会特别的顺利,会遇到一些不可控的问题,比如网络不通?服务不稳定等不可预测的问题。

那么为了保证我们这边的开发顺利性,可能会使用mock这一服务来模拟远程返回的数据,进行更好的业务联调。

什么是mock?

简单介绍一下mock

"MOCK"通常指的是创建一个模拟的对象或功能,以替代实际的对象或功能,从而进行测试或其他操作。这样做的主要目的是隔离测试环境,使其只关注被测试的部分,而不受其他依赖项的影响。通过使用MOCK,开发者或测试人员可以模拟外部系统、数据库、网络请求或其他难以直接控制的依赖项,从而更容易地控制测试环境,确保测试的准确性和可靠性。

举个🌰

public class CatServiceImpl {void test(){doSomething();CatService.getCat();doSomething();}
}

在上述代码中,如果CatService.getCat()尚未开发完成或者由于一些不可控原因调不通,那么在测试这段代码的时候,整个流程是走不通的,只能注释掉CatService.getCat()这个方法。而mock的作用是能够模拟出一个CatService并调用它的getCat()方法。这样一来的话,可以比较顺了的跑通整个流程。

为什么支持mock?

虽然 mock 服务并不是 RPC 框架的核心能力,但是它的开发成本并不高。而且给 RPC 框架支持 mock后,开发者就可以轻松调用服务接口、跑通业务流程,不必依赖真实的远程服务,提高使用体验,何乐而不为呢?

我们希望能够用最简单的方式 – 比如一个配置,就让开发者使用 mock 服务。

设计方案

上文也讲到了mock旨在创建一个模拟对象,供调用方使用。

但是怎么调用产生一个模拟对象呢?

在这里插入图片描述

仔细想想,是不是可以通过动态代理的方式,产生一个对象,在调用方调用该对象的时候,返回一个固定的返回值,这样是不是就🆗了?

具体实现

1- 我们实现mock是可配置的,通过读取配置信息来获取用户是否开启mock。在之前的RpcConf中添加一个mock属性

..../**** 是否开启模拟数据模式* 默认不开启mock*/private boolean mock = false;

2-在proxy包中添加MockServiceProxy类,用于生成mock模拟服务。其中通过自定义方法getDefaultObject根据方法返回值的类型进行默认值的返回,比如返回值类型为 int的方法,默认返回0,返回值为boolean的方法返回值默认为false。

/*** @version 1.0* @Author jerryLau* @Date 2024/4/12 15:42* @注释 MockServiceProxy 类* 采用JDK动态代理* 开启Mock服务代理*/
@Slf4j
public class MockServiceProxy implements InvocationHandler {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Class<?> returnType = method.getReturnType();log.info("MockServiceProxy invoke method: {}, returnType: {}", method.getName(), returnType.getName());return getDefaultObject(returnType);}/**** 根据返回类型返回默认值* @param returnType* @return*/public Object getDefaultObject(Class<?> returnType) {log.info("MockServiceProxy getDefaultObject returnType: {}", returnType.getName());if (returnType == int.class) {return 0;} else if (returnType == long.class) {return 0L;} else if (returnType == double.class) {     // double 类型默认值是 0.0return 0.0;} else if (returnType == boolean.class) {return false;        // boolean 类型默认值是 false} else if (returnType == Short.class) {return (short) 0;}//对象返回nullreturn null;}
}

3-在代理工厂类ServiceProxyFactory中添加关于mock的判定以及返回一个mock代理对象,通过获取配置管理器中用户是否开启了mock,如果开启了mock,则返回一个mock代理对象。

//配置管理器中是否开启Mock模式if (RPCGlobalConfHolder.getRpcConfig().isMock()) {return (T) getMockProxy(serviceClass);}/**** get mock proxy* @param serviceClass* @return* @param <T>*/public static <T> T getMockProxy(Class<T> serviceClass) {return (T) Proxy.newProxyInstance(serviceClass.getClassLoader(),new Class[]{serviceClass}, new MockServiceProxy());}

简单测试

上述过程简单实现了mock的自定义配置,接下来我们可以简单的进行测试。

1-将example-common模块中的获取cat接口中添加一个默认方法getCatCount,用于获取猫的数量

/*** 获取猫咪数量* @return*/default int getCatCount() {return 100;}

在默认不开启mock的情况下,在example-consumerEasyConsumer简单消费者中调用获取猫咪数量的方法

在默认不开启mock的时候,可以看到获取到的猫咪数量是默认的数量100

在这里插入图片描述

修改application.yml文件 配置mock属性为 true,开启mock

RPC:name: "ape-rpc1"serverPort: 8080version: "1.0.0"serverHost: "localhost233"mock: true

在此运行消费者程序,发现获取到的猫咪的数量是0,而不是100,说明mock生效。

在这里插入图片描述


至此,我们实现了简易版的PRC框架中的mock功能

码字不易,希望大家能够一键三连🌝⭐🌟


代码仓库 ape-rpc: 轮子项目,手动实现rpc github🌐 || ape-rpc: 轮子项目,手动实现rpc gitee🌐


http://www.ppmy.cn/news/1449353.html

相关文章

抖音IP打造品牌规划流量运营方案推广计划书

【干货资料持续更新&#xff0c;以防走丢】 抖音IP打造品牌规划流量运营方案推广计划书 部分资料预览 资料部分是网络整理&#xff0c;仅供学习参考。 50页可编辑&#xff08;完整资料包含以下内容&#xff09; 目录 详细的抖音运营方案&#xff0c;帮助品牌在抖音平台上提升…

长亭安全运营实习一面

这次面试感觉真的跟面试官日常聊天一样。 首先百年不变的就是自我介绍&#xff1b; 跟我讲了一下这个岗位大概是干什么的&#xff0c;看看我的预期是什么&#xff1f; 然后问了俩仨个问题&#xff0c;都很基础&#xff0c;将的sql注入&#xff0c;ssrf这些为什么会产生&#xf…

保存钉钉群直播回放下载:直播回放下载步骤详解

今天&#xff0c;我们就来拨开云雾&#xff0c;揭开保存钉钉群直播回放的神秘面纱。教会你们如何下载钉钉群直播回放 首先用到的工具我全部打包好了&#xff0c;有需要的自己下载一下 钉钉群直播回放工具下载&#xff1a;https://pan.baidu.com/s/1WVMNGoKcTwR_NDpvFP2O2A?p…

NFS服务器(linux-linux)

目录 简介 NFS背景介绍 生产应用场景 NFS工作原理 示例图 流程 NFS的使用 安装 配置文件 主配置文件分析 实验1 NFS账户映射 实验2&#xff1a; 实验3 autofs自动挂载服务 产生原因 安装 配置文件分析 实验4 实验5 简介 NFS背景介绍 NFS是一种古老的用于…

flutter-解决AppBar背景色为白色带滚动时不生效的bug

作为初学flutter的小白来说&#xff0c;今天在模仿小米商城app的首页appbar的时候&#xff0c;遇到一个奇怪的问题&#xff0c;就是修改AppBar的backgroundColor,在首页上拉滚动时&#xff0c;设置的白色背景色不生效&#xff0c;背景色变成不是淡灰色&#xff0c;其他深色不影…

【经典面试题】JavaScript中的异步操作与回调地狱解决方法

JavaScript中的异步操作与回调地狱解决方法 在现代的Web开发中&#xff0c;JavaScript扮演着极为重要的角色&#xff0c;尤其是在处理网络请求、文件操作或者任何可能耗费时间的操作时。为了不阻塞程序的执行&#xff0c;JavaScript 提供了异步编程模型。本文将介绍JavaScript…

react 学习笔记二:ref、状态、继承

基础知识 1、ref 创建变量时&#xff0c;需要运用到username React.createRef()&#xff0c;并将其绑定到对应的节点。在使用时需要获取当前的节点&#xff1b; 注意&#xff1a;vue直接使用里面的值&#xff0c;不需要再用this。 2、状态 组件描述某种显示情况的数据&#…

【webrtc】MessageHandler 8: 基于线程的消息处理:处理音频输入输出断开

m98代码,看起来m114 去掉了MessageHandler :音频的录制和播放 都使用了on message,但只是用来通知并处理流的断开的。AAudioRecorder AAudioRecorder 处理流断开 OnErrorCallback :有可能 错误回调是别处来的,是其他线程, 但是这个错误的处理要再自己的线程执行: 音频播…