Closed liauraljl closed 2 years ago
你说的是指org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
,是吧?@liauraljl
目前没有直接支持Spring
的ThreadPoolTaskExecutor
。
我思考一下
TTL
是否应该做这个功能以发一个新版本支持。 💕 @liauraljl
先直接解决你问题的一个做法是:
可以自己先模仿 com.alibaba.ttl.threadpool.TtlExecutors.getTtlExecutor()
,自己实现一个对应的工具方法:
照着实现,是比较简单的 :")
如果通过agent来增强的,是否就无需“每次Runnable和Callable传入线程池时的修饰”以及“getTtlAsyncTaskExecutor()方法“了? 看Spring的ThreadPoolTaskExecutor代码,最终还是调用的是JDK的Executor.execute。
如果通过agent来增强的,是否就无需“每次Runnable和Callable传入线程池时的修饰”以及“getTtlAsyncTaskExecutor()方法“了? 看Spring的ThreadPoolTaskExecutor代码,最终还是调用的是JDK的Executor.execute。
我做了一些简单测试:
在Agent
增强的使用方式下,Spring
的ThreadPoolTaskExecutor
的TTL
传递是 OK的。 @liauraljl
# 原因就如 @superbool 所说,Spring
的ThreadPoolTaskExecutor
是基于JDK
的Executor
来实现的。
具体可以结合你的业务 再测试一下。 @liauraljl
@oldratlee 是的,一开始我们只用了api的方式,后面使用agent方式,是不需要改造的
@superbool 我说的这个问题就是在使用api的情况下,这个是前提哈;agent是兼容的,但是毕竟涉及到应用部署方式的改造,使用代价还是比较大的,可能有些开发人员希望仅通过引入依赖便可使用ttl的功能;
我们这边链路监控,灰度,服务治理等一些功能都是通过agent方式做的,已经有一个相对完善的agent管理系统了,所以已经弃用api方式
我之前在项目里也遇到了类似的问题,然后自己根据ThreadPoolTaskExecutor,实现了一个TtlThreadPoolTaskExecutor。一开始想对ThreadPoolTaskExecutor底层的threadPoolExecutor进行包装,后来发现它并未对外暴露,这个想法不成立。那我们就着手在执行时进行包装,复写它的execute(),submit()等方法。这种方式,也不会干扰其它的方法,对内部线程池参数的修改。具体如下,实现起来很简单:
public class TtlThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
/**
* 错误提示语
*/
private static final String ERROR_MESSAGE = "task不能为空";
@Override
public void execute(Runnable task) {
super.execute(Objects.requireNonNull(TtlRunnable.get(task), ERROR_MESSAGE));
}
@Override
public void execute(Runnable task, long startTimeout) {
super.execute(Objects.requireNonNull(TtlRunnable.get(task), ERROR_MESSAGE), startTimeout);
}
@Override
public Future<?> submit(Runnable task) {
return super.submit(Objects.requireNonNull(TtlRunnable.get(task), ERROR_MESSAGE));
}
@Override
public <T> Future<T> submit(Callable<T> task) {
return super.submit(Objects.requireNonNull(TtlCallable.get(task), ERROR_MESSAGE));
}
@Override
public ListenableFuture<?> submitListenable(Runnable task) {
return super.submitListenable(Objects.requireNonNull(TtlRunnable.get(task), ERROR_MESSAGE));
}
@Override
public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
return super.submitListenable(Objects.requireNonNull(TtlCallable.get(task), ERROR_MESSAGE));
}
}
@oldratlee @liauraljl
目前看来Spring的ThreadPoolTaskExecutor
可以不用额外的支持:
API
方式 可以用已有的TTL ExecutorService Wrapper
方法Agent
方式 可以正常工作。这个 Issue 先 close 了。
如果ThreadPoolTaskExecutor 不支持的话 下面的这个配置 在spring注入的时候 如果使用 ThreadPoolTaskExecutor 来引用启动就会报类型不匹配
@whaceyou 如果要注入ThreadPoolTaskExecutor
类型,
post processor
直接处理成(ttl)Executor
,否则自然是类型不匹配。master
开发分支升级版本到v3.x
;TTL v3.x
重点会是
Spring
/Spring Boot
的集成JDK
标准库涉及类的集成,v2
已经做了TTL Agent
的扩展开放,方便三方自己做类增强的集成。
TTL
库中不可能都做支持API
(核心是Transmitter
),v2
已经开放了TTL
核心功能,v2
已经是开放的,即
TTL
库中才能实现。TTL
库外部来扩展实现。在TTL
项目中,扩大集成范围,可以优化大家平时常用场景开箱即用的使用体验。
其实,不少方便使用的TTL
集成/增强,各个大厂是会有实现的,但并没开源出来;这些使用便利的地方值得进一步解决得更好。
如果ThreadPoolTaskExecutor 不支持的话 下面的这个配置 在spring注入的时候 如果使用 ThreadPoolTaskExecutor 来引用启动就会报类型不匹配
我试了好像这样可以
if (bean instanceof ThreadPoolTaskExecutor && !(bean instanceof TtlEnhanced)) {
ThreadPoolTaskExecutor poolTaskExecutor = (ThreadPoolTaskExecutor) bean;
poolTaskExecutor.setTaskDecorator(TtlRunnable::get);
poolTaskExecutor.initialize();
return poolTaskExecutor;
}
我们在通过
ThreadPoolTaskExecutor
定义线程池时,想省去每次Runnable
和Callable
传入线程池时的修饰。能否提供类似
getTtlExecutorService
的getTtlAsyncTaskExecutor
方法呢?