架构之旅
源码之 Java 基础
从 Hello, World! 说起
Hello, World! 之 标准输入流
从 流 到 Java IO
pulsar 文档
pulsar 本地开发集群搭建
jvm - sandbox
流量回放流程分析
nacos 笔记
nacos server 启动流程
nacos 集群管理 - ServerMemberManager
dubbo 之 No provider available for the service
-
+
home page
流量回放流程分析
流量回放入口为: com.alibaba.jvm.sandbox.repeater.plugin.core.pulsar.ModulePulsarListener.java 对应的核心代码如下: ```java DefaultFlowDispatcher.instance().dispatch(meta, pr.getData()); ``` 这个调用最终执行的代码如下: ``` @Override public void dispatch(RepeatMeta meta, RecordModel recordModel) throws RepeatException { if (recordModel == null || recordModel.getEntranceInvocation() == null || recordModel.getEntranceInvocation().getType() == null) { throw new RepeatException("invalid request, record or root invocation is null"); } Repeater repeater = RepeaterBridge.instance().select(recordModel.getEntranceInvocation().getType()); if (repeater == null) { throw new RepeatException("no valid repeat found for invoke type:" + recordModel.getEntranceInvocation().getType()); } RepeatContext context = new RepeatContext(meta, recordModel, TraceGenerator.generate()); // 放置到回放缓存中 RepeatCache.putRepeatContext(context); repeater.repeat(context); } ``` 更为核心的类 com.alibaba.jvm.sandbox.repeater.plugin.api.FlowDispatcher.java ### http 请求回放 http 核心代码在 com.alibaba.jvm.sandbox.repater.plugin.http.HttpStandaloneListener 类里面。 ### 回放流程 1. com.alibaba.jvm.sandbox.repeater.plugin.core.impl.api.DefaultEventListener.java 2. com.alibaba.jvm.sandbox.repeater.plugin.core.impl.AbstractInvokePluginAdapter.java 3. com.alibaba.jvm.sandbox.repeater.plugin.core.impl.AbstractInvocationProcessor.java 4. com.alibaba.jvm.sandbox.repeater.plugin.api.FlowDispatcher.java ### 流量录制与回放流程梳理 首先,jvm-sandbox 允许你监听某些类的某些方法,如下: ```java new EventWatchBuilder(moduleEventWatcher) .onClass("com.taobao.demo.Clock") .onBehavior("checkState") .onWatch(new AdviceListener() { /** * 拦截{@code com.taobao.demo.Clock#checkState()}方法,当这个方法抛出异常时将会被 * AdviceListener#afterThrowing()所拦截 */ @Override protected void afterThrowing(Advice advice) throws Throwable { // 在此,你可以通过ProcessController来改变原有方法的执行流程 // 这里的代码意义是:改变原方法抛出异常的行为,变更为立即返回;void返回值用null表示 ProcessController.returnImmediately(null); } }); } ``` 这里,onClass 指定了你要监听的类,onBehavior 指定了你要监听的方法,jvm-sandbox-repeater 的插件均需要实现 getEnhanceModels 方法,该方法指定了插件监听的类以及方法,比如 http: ```java @Override protected List<EnhanceModel> getEnhanceModels() { // 拦截javax.servlet.http.HttpServlet#service(HttpServletRequest req, HttpServletResponse resp) EnhanceModel.MethodPattern mp = EnhanceModel.MethodPattern.builder() .methodName("service") .parameterType(new String[]{"javax.servlet.http.HttpServletRequest", "javax.servlet.http.HttpServletResponse"}) .build(); EnhanceModel em = EnhanceModel.builder() .classPattern("javax.servlet.http.HttpServlet") .methodPatterns(new EnhanceModel.MethodPattern[]{mp}) .watchTypes(Event.Type.BEFORE, Event.Type.RETURN, Event.Type.THROWS) .build(); return Lists.newArrayList(em); } ``` 这里,http 插件监听 javax.servlet.http.HttpServlet 类的 service 方法,其入参分别为 javax.servlet.http.HttpServletRequest 以及 javax.servlet.http.HttpServletResponse com.alibaba.jvm.sandbox.repeater.module.RepeaterModule.java 为 repeater 启动后注册模块的类,它调用了 InvokePlugin 的 watch 方法,AbstractInvokePluginAdapter 实现了 InvokePlugin 并在 watch 方法里调用了watchIfNecessary 方法,该方法调用了 getEnhanceModels 并将相关监听信息注册到了 jvm-sandbox,梳理下,我们得出如下结论: jvm-sandbox-repeater 的各个插件,均继承了 AbstractInvokePluginAdapter 类,并实现了getEnhanceModels 方法,该方法定义了该插件观察的类以及方法,即定义了该插件的切点,jvm-sandbox 是提供了运行时动态 aop 功能,所以插件必须得定义自己的切点; AbstractInvokePluginAdapter 又实现了 InvokePlugin 接口,InvokePlugin 接口有个 watch 方法,jvm-sandbox-repeater 定义了一个模块,RepeaterModule,模块名 repeater,jvm-sandbox 会自动加载该模块,而该模块在加载后,又扫描实现了 InvokePlugin 的类,并分别调用其 watch 方法,从而将插件监听的事件注册到了 jvm-sandbox 里面。另外,AbstractInvokePluginAdapter 类里有一个 getEventListener 方法,其提供了默认的 listener,也允许插件覆盖这个实现,这个listener 便是录制与回放的监听,只要插件的切点被触发,该 listener 便由 jvm-sandbox 回调。
十三
Sept. 26, 2021, 6:32 p.m.
转发文档
Collection documents
Last
Next
手机扫码
Copy link
手机扫一扫转发分享
Copy link
关于 MrDoc
觅思文档MrDoc
是
州的先生
开发并开源的在线文档系统,其适合作为个人和小型团队的云笔记、文档和知识库管理工具。
如果觅思文档给你或你的团队带来了帮助,欢迎对作者进行一些打赏捐助,这将有力支持作者持续投入精力更新和维护觅思文档,感谢你的捐助!
>>>捐助鸣谢列表
微信
支付宝
QQ
PayPal
Markdown文件
share
link
type
password
Update password