1

Environment: Webphere 6, Solaris box, Thick client, Java web app.

Number of request can be between 400 - 600. On each request to server, I am creating 15 threads( using Java ExecutorService) for requesting 15 different webservies simultaneously and group all the responses data together and send it back to user. Load test fails at nearly 150 - 170 users. CPU and memory spikes are seen in DB servicing these webservices and eventually after a very short period of time app server too crashes. Response time of webservice is 10-12 sec max and 4-6 secs min. Connection pooling size of the DB is 40.

I am assuming that 150 request are creating 150*15=2250 threads and app server resources are being spiked and hence crashing. So I want to use App server threadpool and have threadCount say 100 (may not be good number..). One thing thats troubling me is, with 100 threads I can process first 6 (6*15 = 90) requests and 10 calls of 7th request. The next requests have to wait for 10-15 secs for getting the threads back and then another 10-15 secs for its own webservice call. Is this approach even good?

Another idea was asynchronous beans provided in Websphere. Which one suits my requirement.

Please suggest!!. Calling one webservice after another takes a total of 15*(lets say 4sec for each request) = 60 secs which is really bad. So calling webserices together is what I want to do.

user418836
  • 847
  • 3
  • 8
  • 19

1 Answers1

1

Managing your threads in application servers is not recommended. If you are using EJBs, the spec disallows that.

Why don't you use use a caching solution to improve the performance? The first few requests will be slower, but once the cache is hot everything will be very fast.

If caching the data is not feasible, what about changing the client to make multiple requests to the server, instead of splitting one request in multiple threads? You would need to change your web application, so that each method would call one web service. The client would call (in parallel) each method needed for the current page and assemble the final result (it may be possible to display partial results if you wish). By doing this you will do work in parallel and won't violate the spec.

I assume you have something like this, in your server:

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;
}

In your client:

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

My proposal, is to split the calls in multiple methods:

 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;
 }

In your client:

//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);

By doing this you are calling only your web application, just like before, so there shouldn't be any security issues.

I am not familiar with Websphere, so I can't tell if using its asynchronous beans are better than this, but IMHO you should avoid starting threads manually.

iruediger
  • 933
  • 6
  • 9
  • Thank you for reply "iruediger". Do you mean caching the data retrieved from webservices?. We cannot do this, because the request from user is unique (eg: Input is SSN and output will be all the medical details from many services).. If your suggestion is not data caching, can you please explain a bit more. Thank you – user418836 Jun 10 '11 at 21:47
  • Yes, I was thinking about data caching with something like [Ehcache](http://ehcache.org/). Since that's no feasible for your system, you could change the client to make multiple requests (check my answer). – iruediger Jun 10 '11 at 22:36
  • My client application is a Flash application and all the webservices are external 3rd party services. Flash player has an internal security measure that would not allow to interact with other servers other than its hosting server. The only way it can happen is, all these 3rd party servers must have crossdomain.xml in their servers with access to our servers domain. No service provider will agree for it. Only option is to call these services from our app server. we are back at square one again. – user418836 Jun 12 '11 at 04:21
  • You don't need to interact with the other servers directly. Your web app can delegate the requests received from the client. I assume your webapp has one method that calls all the web services, my proposal was to split this in multiple methods (in your hosting server), where each one would call a different web service, the client would assemble the final result. I'll add some pseudo code to my answer to make it clearer. – iruediger Jun 12 '11 at 15:50
  • Thanks iruediger. I will propose this solution and ask the testing team to do a load test with this approach. On the other hand, this may option may not work completely because first call to 9 webserices are made and the result of the 9 webservices are analyzed and depending on the result, calls to the next set of webservices and DB are made. Its business logic.. . This kind of logic in the frontend ???. Its very hard to convince everybody with this approach. I am sorry I did not mentioned the actual call procedure. – user418836 Jun 13 '11 at 18:52
  • If you need to make decisions based on the result of 9 web services, how did you manage to call the 15 web services simultaneously? From what I understand, you can't parallelize all calls, no matter what solution you choose. I agree that the client shouldn't have any business logic, but since you can't make all calls in parallel your web application would expose 9 methods and those server side methods would be responsible for calling other web services/DB functions and return the result. As I said on my answer, I am not familiar with Websphere, maybe those async beans are a better solution. – iruediger Jun 13 '11 at 22:33