本文不提及TTL的作用,仅从源码层面分析TTL是怎么使用JavaAgent来动态代理的
依赖如下:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>2.11.4</version>
</dependency>
JavaAgent字节码方式增强
代码入口
com.alibaba.ttl.threadpool.agent.TtlAgent
使用方式
启动jar的时候,附加上参数-javaagent:/xx/transmittable-thread-local.jar(目录自己放好)
/opt/soft/jdk/jdk1.8.0_191/bin/java
-javaagent:/xx/transmittable-thread-local.jar
-jar /opt/xxx.jar
源码分析
执行步骤
第一步:解析参数(可不传),将“xx:xx”解析为Map<String, String>
常用参数:
ttl.agent.disable.inheritable.for.thread.pool:true
ttl.agent.logger:STDOUT
ttl.agent.enable.timer.task:false第二步:设置日志输出参数类型,比如STDOUT(不设置默认就是STDOUT, loggerImplType = 0)
STDOUT: 标准输出
STDERR: 标准错误输出第三步:组装JavassistTransformlet,分为三种类型如下
TtlExecutorTransformlet处理的类:ThreadPoolExecutor及其子类、ScheduledThreadPoolExecutor
TtlForkJoinTransformlet处理的类:ForkJoinTask、ForkJoinPool
默认开启。TtlTimerTaskTransformlet处理的类:仅处理TimeTask子类第四步:调用生效的时机到了
执行生效方法:inst.addTransformer(transformer, true);
TtlAgent入口premain()方法
Java中的javaAgent一般会涉及到 MANIFEST.MF配置类、premain()方法入口,下面来解析
- MANIFEST.MF配置如下:
可见Premain-Class指向了com.alibaba.ttl.threadpool.agent.TtlAgent类
Manifest-Version: 1.0
Created-By: Apache Maven 3.5.4
Built-By: jerry
Build-Jdk: 11.0.1
Boot-Class-Path: transmittable-thread-local-2.10.2.jar
Can-Redefine-Classes: false
Can-Retransform-Classes: true
Can-Set-Native-Method-Prefix: false
Premain-Class: com.alibaba.ttl.threadpool.agent.TtlAgent
接来下解析TllAgent.java入口类,其premain()方法如下
/** TTL javaAgent字节码增强premain入口类 **/
public static void premain(String agentArgs, @NonNull Instrumentation inst) {
// 第一步:解析参数(可不传),将“xx:xx”解析为Map<String, String>
// 常用参数:ttl.agent.disable.inheritable.for.thread.pool:true
// ttl.agent.logger:STDOUT
// ttl.agent.enable.timer.task:false
kvs = splitCommaColonStringToKV(agentArgs);
// 第二步:设置日志输出参数类型,比如STDOUT(不设置默认就是STDOUT, loggerImplType = 0)
// - STDOUT: 标准输出
// - STDERR: 标准错误输出
Logger.setLoggerImplType(getLogImplTypeFromAgentArgs(kvs));
final Logger logger = Logger.getLogger(TtlAgent.class);
try {
logger.info("[TtlAgent.premain] begin, agentArgs: " + agentArgs + ", Instrumentation: " + inst);
// 获取是否开启 "关闭继承" 的能力,不传默认返回false
final boolean disableInheritableForThreadPool = isDisableInheritableForThreadPool();
// 第三步:组装JavassistTransformlet
final List<JavassistTransformlet> transformletList = new ArrayList<JavassistTransformlet>();
// TtlExecutorTransformlet处理的类:ThreadPoolExecutor及其子类、ScheduledThreadPoolExecutor
transformletList.add(new TtlExecutorTransformlet(disableInheritableForThreadPool));
// TtlForkJoinTransformlet处理的类:ForkJoinTask、ForkJoinPool
transformletList.add(new TtlForkJoinTransformlet(disableInheritableForThreadPool));
// 默认开启。TtlTimerTaskTransformlet处理的类:仅处理TimeTask子类
if (isEnableTimerTask()) transformletList.add(new TtlTimerTaskTransformlet());