通用的底层埋点都是怎么做的?( 二 )

CatMonitorRedisConnection 中对原生的 RedisConnection 做了增强,也不会影响原有的 RedisConnection 的功能 。
public class CatMonitorRedisConnection implements RedisConnection {private final RedisConnection connection;private CatMonitorHelper catMonitorHelper;public CatMonitorRedisConnection(RedisConnection connection) {this.connection = connection;this.catMonitorHelper = new CatMonitorHelper();}@Overridepublic byte[] get(byte[] key) {return catMonitorHelper.execute(RedisCommand.GET, key, () -> connection.get(key));}}JAVA AgentJava Agent 可以在运行期将已经加载的类的字节码进行变更,可以加入我们需要进行监控的代码逻辑 。无需对原有代码进行改造,零侵入性 。
【通用的底层埋点都是怎么做的?】在非常多优秀的开源框架中都看到了 Java Agent 的应用,像 APM 框架 SkyWalking,异步传递上下文 transmittable-thread-local 等 。
Java Agent 相对其他的方式来说,还是有一定的门槛,毕竟不是日常开发中经常会用到的技术点 。如果想了解这种扩展方式,可以看看一些已经用了的开源框架的源码,就知道大概怎么使用了 。下面贴一段 transmittable-thread-local 中对线程池进行扩展的代码吧,主要就是利用了 javassist 操作字节码 。
try {final CtMethod afterExecute = clazz.getDeclaredMethod("afterExecute", new CtClass[]{runnableClass, throwableClass});// unwrap runnable if IsAutoWrApperString code = "$1 = com.alibaba.ttl.threadpool.agent.internal.transformlet.impl.Utils.unwrapIfIsAutoWrapper($1);";logger.info("insert code before method " + signatureOfMethod(afterExecute) + " of class " + afterExecute.getDeclaringClass().getName() + ": " + code);afterExecute.insertBefore(code);modified = true;} catch (NotFoundException e) {// clazz does not override afterExecute method, do nothing.}关于作者:尹吉欢,简单的技术爱好者,《Spring Cloud 微服务-全栈技术与案例解析》, 《Spring Cloud 微服务 入门 实战与进阶》作者, 公众号猿天地发起人 。




推荐阅读