与其他探针放在一起使用的时候,如果ttlagent顺序在其他探针之后,探针失效无法跨线程
private static ThreadLocal<String> threadLocal = new TransmittableThreadLocal<>();
ExecutorService executorService = Executors.newFixedThreadPool(2);
@GetMapping("local")
public String ttLocal(){
String randomStr = UUID.randomUUID().toString();
threadLocal.set(randomStr);
Runnable runnable= new Runnable() {
@Override
public void run() {
if (!randomStr.equals(threadLocal.get())){
System.out.println("randomStr not equals localStr.");
}
}
};
executorService.execute(runnable);
return "ok";
}
使用TTL Agent加其他Agent,TTL Agent顺序在最后,runnable无法改成TtlRunnable
问题原因:其他探针启动的时候使用了ThreadPoolExecutor,导致TTL Agent没有机会transform ThreadPoolExecutor类
解决方案:在添加transformer之后,将需要的嵌码类retransform一下
使用
TTL Agent加其他Agent,TTL Agent顺序在最后,runnable无法改成TtlRunnable
@will-zdu 在文档 FAQ 中已说明: https://github.com/alibaba/transmittable-thread-local/tree/2.x#-faq
Q1.
TTL Agent与其它Agent(如Skywalking、Promethues)配合使用时不生效?配置
TTL Agent在最前的位置,可以避免与其它其它Agent配合使用时,TTL Agent可能的不生效问题。配置示例:java -javaagent:path/to/transmittable-thread-local-2.x.y.jar \ -javaagent:path/to/skywalking-agent.jar \ -jar your-app.jar原因是:
- 像
Skywalking这样的Agent的入口逻辑(premain)包含了线程池的启动。- 如果配置在这样的
Agent配置在前面,到了TTL Agent(的premain)时,TTL需要加强的线程池类已经加载(load)了。TTL Agent的TtlTransformer是在类加载时触发类的增强;如果类已经加载了会跳过TTL Agent的增强逻辑。
解决方案:在添加transformer之后,将需要的嵌码类retransform一下
嗯嗯,欢迎讨论与实现 @will-zdu
@will-zdu PR #526 的实现,你有测试验证过吗(比如在你的应用中可以解决问题)?
这样简单处理可能是不行的,具体可以看看已有的讨论 Issue #226
已经测试验证过了,问题已经解决,当然我只测试了ThreadPoolExecutor类。
我看 #226 里面的讨论是ttl agent会尝试修改类文件结构?如果是这样的话,那确实是存在问题,请问是在那个地方修改了那个类的类文件结构
如果是这样的话,我认为ttl agent这样的修改不太好,修改类的结构在我看来是个不提倡的操作
retransform让TTL Agent的实现变复杂了(如类的加载过程),
会引入还不知道的问题要解决(考虑Java Agent的复杂性),
进而影响TTL Agent整体的稳定性可靠性。
如果只是解决Agent配置的顺序问题,推荐配置TTL Agent到前面吧,简单可靠。 😄 @will-zdu
已经测试验证过了,问题已经解决,当然我只测试了ThreadPoolExecutor类。
当然,你的实现可以自己打个包,在你自己应用中用起来。 💕 @will-zdu 欢迎反馈实现在应用使用中的情况~
我认为ttl agent这样的修改不太好,修改类的结构在我看来是个不提倡的操作
欢迎给出不同的实现与验证 💕
如果没有修改类文件结构,使用retransform transform该类没有任何的问题,以我们探针这么多年的使用经验来说,除了需要短暂的进入safepoint,挂起jvm,没有发现有任何问题,当然进入safepoint是必须的,我觉得可以暂时将ForkJoinPool移除retransform的类列表
我把代码修改了一下,将ForkJoinPool移除retransform的类列表,这样应该是可以工作了,但是如果别的探针触发了ForkJoinPool的retransform,问题依然是存在的