Целесообразно ли использовать поток потоков в этом многопоточном случае? - PullRequest
1 голос
/ 10 июня 2011

Среда: Webphere 6, Solaris box, толстый клиент, веб-приложение Java.

Количество запросов может быть между 400 и 600. При каждом запросе к серверу я создаю 15 потоков (используя Java ExecutorService)для одновременного запроса 15 различных веб-сервисов, группировки всех данных ответов и отправки их обратно пользователю.Нагрузочный тест не проходит почти у 150 - 170 пользователей.Скачки ЦП и памяти наблюдаются в БД, обслуживающей эти веб-сервисы, и в конечном итоге через очень короткое время сервер приложений тоже выходит из строя.Время отклика веб-сервиса составляет максимум 10-12 секунд и минимум 4-6 секунд.Размер пула подключений в БД - 40.

Я предполагаю, что 150 запросов создают 150 * 15 = 2250 потоков, а ресурсы сервера приложений расходуются и, следовательно, вызывают сбой.Поэтому я хочу использовать пул потоков сервера приложений и указать количество потоков, скажем, 100 (может быть, не очень хорошее число ..).Меня беспокоит то, что с 100 потоками я могу обработать первые 6 (6 * 15 = 90) запросов и 10 вызовов 7-го запроса.Следующие запросы должны ждать 10-15 секунд для возврата потоков, а затем еще 10-15 секунд для своего собственного вызова веб-службы.Является ли этот подход даже хорошим?

Еще одна идея - асинхронные компоненты, предоставляемые в Websphere.Какой из них соответствует моему требованию.

Пожалуйста, предложите!Вызов одного веб-сервиса за другим занимает в общей сложности 15 * (скажем, 4 секунды для каждого запроса) = 60 секунд, что очень плохо.Так что объединение веб-серий - это то, что я хочу сделать.

1 Ответ

1 голос
/ 10 июня 2011

Управление вашими потоками на серверах приложений не рекомендуется.Если вы используете EJB, спецификация запрещает, чтобы .

Почему бы вам не использовать решение для кэширования для повышения производительности?Первые несколько запросов будут выполняться медленнее, но после того, как кеш нагреется, все будет очень быстро.

Если кэширование данных неосуществимо, как насчет изменения клиента для выполнения нескольких запросов к серверу вместо разделенияодин запрос в несколько потоков?Вам необходимо изменить свое веб-приложение, чтобы каждый метод вызывал один веб-сервис.Клиент будет вызывать (параллельно) каждый метод, необходимый для текущей страницы, и собирать конечный результат (при желании можно отобразить частичные результаты).Делая это, вы будете работать параллельно и не будете нарушать спецификацию.

Я предполагаю, что у вас есть что-то подобное на вашем сервере:

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

Делая это, вы вызываете только ваше веб-приложение, как и раньше, поэтому не должно быть никаких проблем с безопасностью.

Я не знаком с Websphere, поэтому не могу сказать, лучше ли использовать его асинхронные bean-компоненты, но IMHO вам следует избегать запуска потоков вручную.

...