alibaba / transmittable-thread-local

📌 a missing Java std lib(simple & 0-dependency) for framework/middleware, provide an enhanced InheritableThreadLocal that transmits values between threads even using thread pooling components.
https://github.com/alibaba/transmittable-thread-local
Apache License 2.0
7.66k stars 1.69k forks source link

关于TtlForkJoinTransformlet中直接修改ForkJoinTask的实现 #205

Closed Yelijah closed 3 years ago

Yelijah commented 4 years ago

因为一些特殊原因, 必须要运行时动态agent,现已基本完成。

但是java.lang.instrument.Instrumentation#retransformClasses不支持在transform中为ForkJoinTask添加fields:

image image


Q1. 不知能否改写TtlForkJoinTransformlet, 使其不直接修改ForkjoinTask, 转而修改ForkJoinPool? Q2. 并且TtlCallable和TtlRunnable都是通过包装类形式实现, 为何TtlRecursiveTask会是抽象类实现?

oldratlee commented 4 years ago

但是java.lang.instrument.Instrumentation#retransformClasses不支持在transform中为ForkJoinTask添加fields:

关于retransformClasses,我也没有使用过。关于这方面可以通过Agent的官方文档来了解确认。

添加fields不成功,可能和Agent的设置有关系。你可以试试: @Yelijah

https://github.com/alibaba/transmittable-thread-local/blob/06ec7da538f5c0e909883f6f6d207d0dd35d2ad2/pom.xml#L268-L272

@Yelijah 有了验证结果,可以反馈一下 :")

PS: 关于运行时动态加载Agent的Issue:支持运行时加载TTL agent #169


因为一些特殊原因, 必须要运行时动态agent

能展开来说一下你的需求场景、问题吗? @Yelijah

这样能够


Q1. 不知能否改写TtlForkJoinTransformlet, 使其不直接修改ForkjoinTask, 转而修改ForkJoinPool? Q2. 并且TtlCallable和TtlRunnable都是通过包装类形式实现, 为何TtlRecursiveTask会是抽象类实现?

修饰ForkjoinTask而不是ForkJoinPool,实现更简单可靠。(ForkJoinPool没有找到可靠的实现方式)

相关的说明Issue:TtlExecutors怎么没有包装ForkJoinPool的方法 #200

TtlRecursiveTask是抽象类实现,原因是ForkJoin本身的API设计不一样。

ForkJoin功能实现方式,ForkJoinPool没有 以接口/语义方式 来提供,不方便统一可靠方式的截面拦截 要可靠实现ForkJoinPool包装有困难。

相关的更多说明参见:


上面提到的TTL设计与实现困难/问题,欢迎解法与建议 😄 @Yelijah

Yelijah commented 3 years ago

需要动态agent的场景是:

oldratlee commented 3 years ago

需要动态agent的场景是:

  • To B的web应用,需要适配多种web容器环境
  • 让客户自行去加启动参数,比较不可控

为了避免升级改动业务代码,让像中间件基础这类的解决方案对业务更透明(如SkywalkingPromethues), 使用Java Agent类加强的方式,是业界 比较常见与主流的方式。

可能很难有 其它更好的透明技术方案,当然对应要做的是 配置JVM的启动参数; 相对各个升级改动业务代码,Agent方案还相对实施成本还是比较低的。

也期望业界 能找到 更简单(如 无需JVM启动参数)的解决方式。 😁 @Yelijah