在这个多线程案例中是否使用线程池是可取的?

时间:2011-06-10 18:44:56

标签: multithreading asynchronous javabeans simultaneous-calls

环境:Webphere 6,Solaris box,胖客户端,Java Web应用程序。

请求的数量可以在400-600之间。在每次请求到服务器时,我创建15个线程(使用Java ExecutorService)同时请求15个不同的webservies并将所有响应数据组合在一起并将其发送回用户。 负载测试失败,接近150-170名用户。在为这些Web服务提供服务的数据库中可以看到CPU和内存峰值,并且最终在很短的时间内app服务器崩溃。 Web服务的响应时间最长为10-12秒,最小为4-6秒。 DB的连接池大小为40。

我假设150个请求正在创建150 * 15 = 2250个线程,并且应用服务器资源正在被飙升并因此崩溃。所以我想使用App服务器threadpool并让threadCount说100(可能不是好号码..)。令我困扰的一件事是,有100个线程我可以处理前6个(6 * 15 = 90)个请求和10个第7个请求的调用。下一个请求必须等待10-15秒才能恢复线程,然后再等待10-15秒以进行自己的webservice调用。这种方法甚至是好的吗?

另一个想法是Websphere中提供的异步bean。哪一个适合我的要求。

请建议!!一个接一个地调用一个web服务总共需要15 *(假设每个请求4秒)= 60秒,这真的很糟糕。因此,调用webserices是我想要做的。

1 个答案:

答案 0 :(得分:1)

不建议在应用程序服务器中管理线程。如果您使用的是EJB,那么规范disallows that

为什么不使用缓存解决方案来提高性能?前几个请求会比较慢,但一旦缓存很热,一切都会非常快。

如果缓存数据不可行,那么更改客户端以向服务器发出多个请求,而不是在多个线程中拆分一个请求呢?您需要更改Web应用程序,以便每个方法都可以调用一个Web服务。客户端将调用(并行)当前页面所需的每个方法并汇总最终结果(如果您愿意,可以显示部分结果)。通过这样做,您将并行工作,不会违反规范。

我认为你的服务器中有这样的东西:

public Result retriveData(Long id) {
   Result myResult = new Result();
   //...
   //do some stuff
   myResult.setSomeData(slowWebService1.retriveSomeData(id));
   myResult.setSomeOtherData(slowWebService2.retriveSomeOtherData(id));
   myResult.setData(slowWebService3.retriveData(id));
   return myResult;
}

在您的客户中:

Result result = webApplication.retriveData(10);
//use the result

我的建议是用多种方法拆分调用:

 public SomeData retriveSomeData(Long id) {
    //do some stuff
    SomeData data = slowWebService1.retriveSomeData(id);
    //do more stuff
    return data;
 }

 public SomeOtherData retriveSomeOtherData(Long id) {
    //do some stuff
    SomeOtherData data = slowWebService2.retriveSomeOtherData(id);
    //do more stuff
    return data;
 }

 public Data retriveData(Long id) {
    //do some stuff
    Data data = slowWebService3.retriveData(id);
    //do more stuff
    return data;
 }

在您的客户中:

//Call these methods in parallel, if you were using Swing, this could be done with
//SwingWorker (I have no idea how to it with Flash :)). 
//You can either wait for all methods to return or show partial results.
callInBackground(webApplication.retriveSomeData(10), useDataWhenDone);
callInBackground(webApplication.retriveSomeOtherData(10), useDataWhenDone);
callInBackground(webApplication.retriveData(10), useDataWhenDone);

通过执行此操作,您只需像以前一样调用您的Web应用程序,因此不会出现任何安全问题。

我不熟悉Websphere,所以我不知道使用它的异步bean是否比这更好,但恕我直言你应该避免手动启动线程。