使用EJB的正确方法异步方法
我有两个任务需要执行,分别是task1
和task2
,它们是相同业务流程的一部分。当task1
完成时,我必须对最终用户做出响应,因此它的响应时间必须最小化。使用EJB的正确方法异步方法
我目前的做法是执行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
我的问题是,这将是实现我想要在这里实现有道。
另一种方法是增加“工作请求队列管理控制台中“EJB异步方法调用设置”的大小。这是一个队列,在实际的线程池本身之前,所以这可能会给你多一点时间。
理想情况下,这应该与上面提到的超时结合使用。
这似乎是一个不错的选择。默认情况下,它由运行时间处理,并取决于分配的线程数量,但我无法弄清楚有多少。请问websphrere管理控制台的最后一行'运行时当前使用20中较大的值和最大线程数的值是否有意义? – ares
看着你的图像,我认为它是“15或20中较大的一个”,因此在你的情况下它应该是20.你可以保持最大的线程池大小,并且将你的队列增加到更大。我希望*队列应该有一个很小的内存/处理器占用空间,所以它可以存储你对task2的等待请求,同时让现有的请求完成并保持在你的硬件限制之内。但是如果任务2可以无限期地完成,那么我认为超时将是一条路 –
我认为@AccessTimeout是你在找什么。我看到一个示例here 这将限制.doTask2()可以运行的时间并避免您的问题。
@Stateless
public class SessionBean1 {
@Inject
SessionBean2 sessionBean2;
public void doTask1(){
// task one stuff
sessionBean2.doTask2();
}
}
SessionBean2
@Stateless
public class SessionBean2 {
@AccessTimeout(60000)//default timeunit is TimeUnit.MILLISECONDS
@Asynchronous
public void doTask2(){
// do task2 stuff
}
}
作为替代:
为了限制时的异步过程可能需要,使用handle.get(XX,TimeUnit.xx );方法。您还需要返回Future,而不是仅仅使其失效。
我希望这适合您的使用情况下,您将需要调用。获得
@Stateless
public class SessionBean1 {
@Inject
SessionBean2 sessionBean2;
public void doTask1(){
// task one stuff
Future<Void> handle = sessionBean2.doTask2();
// do other stuff
handle.get(10, TimeUnit.SECONDS);//If you want to block later
}
}
SessionBean2
@Stateless
public class SessionBean2 {
@Asynchronous
public Future<Void> doTask2(){
// do task2 stuff
new AsyncResult<Void>(Void);
}
}
如果您使用的是Java EE 7,您可以使用@AccessTimeout(value = xx)批注,但我认为Websphere是Java EE 6? – rjdkolb
@mattfreake:如链接[image](http://2.1m.yt/itzn6So。jpg),异步方法请求的数量是有限的,并且取决于异步线程的数量。我可以增加线程的数量,但即使task2表现不佳,我的task1仍然需要等待。此外,线程的数量不受硬件配置的限制。 – ares
使用@rjdkolb建议的JMS队列的想法是一个更好的主意,如果调整线程池的大小是有问题的。 –