网站设计过程怎么写,网站建设全包设计,万能视频解析接口网站怎么做,网站安装教程一、配置初见 源码里提供的控制台截图如下#xff1a;#xff08;怎么搭建自己去百度#xff09; 从中取出对应的配置如下#xff1a; { degrade: false, //阻断能力 exceptionThreshold: 1000, //异常采样率 httpEntrancePatterns怎么搭建自己去百度 从中取出对应的配置如下 { degrade: false, //阻断能力 exceptionThreshold: 1000, //异常采样率 httpEntrancePatterns: [ ^/app/v1/order/.*$ ], javaEntranceBehaviors: [ //主调用配置 { classPattern: com.test.order.service.pay.PayService, includeSubClasses: false, //是否对内部类生效 methodPatterns: [ payCallback ] } ], javaSubInvokeBehaviors: [ //子调用配置 { classPattern: com.test.backend.util.RedisUtil, includeSubClasses: false, methodPatterns: [ * ] } ], pluginIdentities: [ //加载的插件 redis, http, java-entrance, java-subInvoke, mybatis, ibatis, dubbo-provider, dubbo-consumer ], repeatIdentities: [ //回放插件 java, http, dubbo ], sampleRate: 10000, //采样率最高10000 useTtl: true //开启ttl主子线程变量同步主要应对多线程场景下的采集} 接下来我们通过源码一步一步来看下具体的配置过程 二、启动过程 repeater插件的启动入口见com.alibaba.jvm.sandbox.repeater.module.RepeaterModule#loadCompleted 基本流程就是 拉取配置 初始化配置 发起心跳 Override public void loadCompleted() { //这里启动一个线程去进行做加载主要是为了不阻断sandbox的模块加载流程 ExecutorInner.execute(new Runnable() { Override public void run() { //standalone模式 我们在项目应用过程中是不需要考虑的所以configManager就是DefaultConfigManager configManager StandaloneSwitch.instance().getConfigManager(); broadcaster StandaloneSwitch.instance().getBroadcaster(); invocationListener new DefaultInvocationListener(broadcaster); RepeaterResultRepeaterConfig pr configManager.pullConfig(); if (pr.isSuccess()) { log.info(pull repeater config success,config{}, pr.getData()); ClassloaderBridge.init(loadedClassDataSource); //启动的核心逻辑就在这里 initialize(pr.getData()); } } }); //心跳机制 heartbeatHandler new HeartbeatHandler(configInfo, moduleManager); heartbeatHandler.start(); } 所以配置相关的核心使用逻辑在 com.alibaba.jvm.sandbox.repeater.module.RepeaterModule#initialize里 读取配置 初始化invokePlugin插件列表 初始化repeater插件列表目前实现的有http、java、dubbo SubscribeSupporter插件初始化默认实现 RepeatSubscribeSupporter private synchronized void initialize(RepeaterConfig config) { //确保一个周期里面只初始化一次 if (initialized.compareAndSet(false, true)) { try { ApplicationModel.instance().setConfig(config); // 特殊路由表; 这个特殊路由表是方便插件需要访问repeater不支持的类 PluginClassLoader.Routing[] routingArray PluginClassRouting.wellKnownRouting(configInfo.getMode() Mode.AGENT, 20L); String pluginsPath; if (StringUtils.isEmpty(config.getPluginsPath())) { pluginsPath PathUtils.getPluginPath(); } else { pluginsPath config.getPluginsPath(); } //这个其实是一个类加载器 lifecycleManager new JarFileLifeCycleManager(pluginsPath, routingArray); // 装载插件 invokePlugins lifecycleManager.loadInvokePlugins(); for (InvokePlugin invokePlugin : invokePlugins) { try { // 根据配置中的pluginIdentities判断是否要注入相关拦截机制 if (invokePlugin.enable(config)) { log.info(enable plugin {} success, invokePlugin.identity()); invokePlugin.watch(eventWatcher, invocationListener); invokePlugin.onConfigChange(config); } } catch (PluginLifeCycleException e) { log.info(watch plugin occurred error, e); } } // 装载回放器 ListRepeater repeaters lifecycleManager.loadRepeaters(); for (Repeater repeater : repeaters) { if (repeater.enable(config)) { repeater.setBroadcast(broadcaster); } } RepeaterBridge.instance().build(repeaters); // 装载消息订阅器 ListSubscribeSupporter subscribes lifecycleManager.loadSubscribes(); for (SubscribeSupporter subscribe : subscribes) { subscribe.register(); } //用于开启ttl的 TtlConcurrentAdvice.watcher(eventWatcher).watch(config); } catch (Throwable throwable) { initialized.compareAndSet(true, false); log.error(error occurred when initialize module, throwable); } } } 所以回过头再看配置信息里启动配置用到的是pluginIdentities、repeatIdentities 三、java插件启动读取配置javaEntranceBehaviors、javaSubInvokeBehaviors 我们发现配置里还有javaEntranceBehaviors 和 javaSubInvokeBehaviors这2个配置顾名思义就是java主子调用的意思 我们去看代码com.alibaba.jvm.sandbox.repeater.plugin.java.JavaEntrancePlugin的实现发现JavaEntrancePlugin重写了getEnhanceModels MetaInfServices(InvokePlugin.class)public class JavaEntrancePlugin extends AbstractInvokePluginAdapter { private RepeaterConfig config; Override protected ListEnhanceModel getEnhanceModels() { //在这个地方读取对应配置的 if (config null || CollectionUtils.isEmpty(config.getJavaEntranceBehaviors())) { return null;} ListEnhanceModel ems Lists.newArrayList(); for (Behavior behavior : config.getJavaEntranceBehaviors()) { ems.add(EnhanceModel.convert(behavior)); } return ems; } ... 其余代码省略} 同理 JavaSubInvokePlugin 也重写了getEnhanceModels()方法 这里关注一个点java主子调用配置的生效最终是在 com.alibaba.jvm.sandbox.repeater.plugin.core.impl.AbstractInvokePluginAdapter#watchIfNecessary里通过调用sandbox的接口com.alibaba.jvm.sandbox.api.listener.ext.EventWatchBuilder.IBuildingForBehavior#onWatch()来生效的也就意味着需要真正字节码注入之后才会生效所以本质上它的配置也是启动配置的一部分 四、http插件的配置 httpEntrancePatterns 首先肯定是看http插件关于 植入点的实现, 我们发现它的注入点是固定的javax.servlet.http.HttpServlet#service()方法那有关httpEntrancePatterns是在哪里生效的呢 Override protected ListEnhanceModel 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); } 通过代码最终我们最后发现是在com.alibaba.jvm.sandbox.repater.plugin.http.HttpStandaloneListener#doBefore里也就是真正的 切点通知逻辑做的 在拦截http的每次请求后判断是否需要采集 Overrideprotected void doBefore(BeforeEvent event) throws ProcessControlException { ... 冗余代码省略 Object request event.argumentArray[0]; Object response event.argumentArray[1]; if (!(request instanceof HttpServletRequest response instanceof HttpServletResponse)) { return; } HttpServletRequest req (HttpServletRequest) request; HttpServletResponse resp (HttpServletResponse) response; // 根据 requestURI 进行采样匹配 这里取的配置 ListString patterns ApplicationModel.instance().getConfig().getHttpEntrancePatterns(); if (!matchRequestURI(patterns, req.getRequestURI())) { LogUtil.debug(current uri {} cant match any httpEntrancePatterns, ignore this request, req.getRequestURI()); Tracer.getContext().setSampled(false); return; } ...冗余代码省略 } 四、可优化的点 通过上述源码阅读配置这块我觉得有以下几个可优化的点 像sampleRate采样率配置是经常需要手动调整的这类配置可以跟启动配置pluginIdentities等区分开启动配置的修改是需要重启生效或者重新attach生效的 http的配置 以及 java的配置也可以区分开 以下是我这边优化后的界面, 有需要欢迎多交流 本文由 mdnice 多平台发布