Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
Yelijah opened this issue Sep 17, 2020 · 3 comments
Closed

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

Yelijah opened this issue Sep 17, 2020 · 3 comments

Comments

@Yelijah
Copy link

Yelijah commented Sep 17, 2020

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

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

image
image


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

@oldratlee
Copy link
Member

oldratlee commented Oct 5, 2020

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

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

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

  • 改一下(TTL的)Agent设置,如 <Can-Redefine-Classes>true</Can-Redefine-Classes>
  • 并重新打包TTL Jar来验证(通过mvn install

<Premain-Class>com.alibaba.ttl.threadpool.agent.TtlAgent</Premain-Class>
<Boot-Class-Path>${project.artifactId}-${project.version}.jar</Boot-Class-Path>
<Can-Redefine-Classes>false</Can-Redefine-Classes>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
<Can-Set-Native-Method-Prefix>false</Can-Set-Native-Method-Prefix>

@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包装有困难。

相关的更多说明参见:

  • Issue support ForkJoinPool of jdk 7 #76

    ForkJoinTask.exec() 是抽象类方法,不好包装.
    ForkJoinWorkerThread.afterTopLevelExec() 限制包内访问,而且runTask()没有类似beforeTopLevelExec()的方法和执行点。
    以上是我分析过程的思路和遇到的问题记录下.

  • PR support ForkJoinTask. #82

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

@Yelijah
Copy link
Author

Yelijah commented Mar 23, 2021

需要动态agent的场景是:

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

@oldratlee
Copy link
Member

oldratlee commented Mar 23, 2021

需要动态agent的场景是:

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

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

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants