【发布时间】:2016-01-13 10:16:35
【问题描述】:
我有两个任务需要执行,例如 task1 和 task2,它们是同一业务流程的一部分。当task1 完成时,我必须对最终用户做出响应,因此必须尽量缩短响应时间。
我目前的方法是执行task1,并在task1 完成后立即异步调用task2 方法。 task2 很复杂,它的响应时间超出了我的控制,因为它有一些外部依赖性。
@Stateless
public class SessionBean1 {
@Inject
SessionBean2 sessionBean2;
public void doTask1(){
// task one stuff
sessionBean2.doTask2();
}
}
@Stateless
public class SessionBean2 {
@Asynchronous
public void doTask2(){
// do task2 stuff
}
}
在 websphere 8.0(使用中的 EJB 容器)中,同步方法和异步方法由不同的线程池运行。
我最初的假设是,即使task2 表现不佳,task1 也不会产生影响,但遗憾的是这不是真的。
如果task2 性能不佳,异步线程池中的所有线程都将被占用。这将导致task1 等待异步线程空闲,因此task1 会产生影响。
websphrere 服务器日志中的消息:
The request buffer for thread pool WorkManager.WebSphere_EJB_Container_AsynchMethods_Internal_WorkManager has reached its capacity
我的问题是什么是实现我在这里想要实现的目标的正确方法。
【问题讨论】:
-
如果您使用的是 Java EE 7,则可以使用 @AccessTimeout(value = xx) 注释,但我认为 Websphere 是 Java EE 6 ?
-
@mattfreake:与链接的image 一样,异步方法请求的数量是有限的,并且取决于异步线程的数量。我可以增加线程数,但即使几分钟 task2 表现不佳,我的 task1 仍然需要等待。线程数也受硬件配置限制。
-
如果线程池大小有问题,使用@rjdkolb 建议的JMS 队列的想法会更好。
-
@SteveC:目前我正在将
task2的方法参数添加到ConcurrentLinkedQueue,然后在Timer 的帮助下定期轮询它们并调用task2方法。到目前为止,它已经证明是好的。使用 JMS 可能有点过头了,因为task1和task2在同一台服务器上。 -
所有 Java EE 实现都“内置”了 JMS,因此可以在“同一服务器”中运行。
标签: java jakarta-ee asynchronous ejb websphere