Целесообразно ли использовать threadpool в этом случае многопоточности?

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

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

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

Другая идея заключалась в предоставлении асинхронных bean-компонентов в Websphere. Какой из них соответствует моим требованиям.

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


person user418836    schedule 10.06.2011    source источник


Ответы (1)


Не рекомендуется управлять потоками на серверах приложений. Если вы используете 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 вам следует избегать запуска потоков вручную.

person iruediger    schedule 10.06.2011
comment
Спасибо за ответ iruediger. Вы имеете в виду кеширование данных, полученных из веб-сервисов? Мы не можем этого сделать, потому что запрос от пользователя уникален (например: ввод - это SSN, а на выходе будут все медицинские данные из многих служб). Если ваше предложение не касается кэширования данных, не могли бы вы объяснить немного подробнее. Спасибо - person user418836; 11.06.2011
comment
Да, я думал о кэшировании данных с помощью чего-то вроде Ehcache. Поскольку это невозможно для вашей системы, вы можете изменить клиента, чтобы он делал несколько запросов (проверьте мой ответ). - person iruediger; 11.06.2011
comment
Мое клиентское приложение - это Flash-приложение, а все веб-сервисы - внешние сторонние сервисы. Flash player имеет внутреннюю меру безопасности, которая не позволяет взаимодействовать с другими серверами, кроме своего хост-сервера. Единственный способ, которым это может произойти, - все эти сторонние серверы должны иметь на своих серверах crossdomain.xml с доступом к домену наших серверов. Ни один поставщик услуг на это не согласится. Единственный вариант - вызвать эти службы с нашего сервера приложений. мы снова вернулись на круги своя. - person user418836; 12.06.2011
comment
Вам не нужно напрямую взаимодействовать с другими серверами. Ваше веб-приложение может делегировать запросы, полученные от клиента. Я предполагаю, что у вашего веб-приложения есть один метод, который вызывает все веб-службы, мое предложение состояло в том, чтобы разделить его на несколько методов (на вашем сервере хостинга), где каждый будет вызывать разные веб-службы, и клиент будет собирать окончательный результат. Я добавлю к своему ответу псевдокод, чтобы было понятнее. - person iruediger; 12.06.2011
comment
Спасибо iruediger. Я предложу это решение и попрошу команду тестирования провести нагрузочный тест с этим подходом. С другой стороны, этот вариант может не работать полностью, потому что выполняется первый вызов 9 веб-сервисов и анализируется результат 9 веб-сервисов, и в зависимости от результата выполняются вызовы следующего набора веб-сервисов и БД. Его бизнес-логика ... Такая логика во фронтенде ???. В таком подходе очень сложно всех убедить. Мне очень жаль, что я не упомянул саму процедуру вызова. - person user418836; 13.06.2011
comment
Если вам нужно принимать решения на основе результатов 9 веб-сервисов, как вам удалось одновременно вызвать 15 веб-сервисов? Насколько я понимаю, невозможно распараллелить все вызовы, какое бы решение вы ни выбрали. Я согласен с тем, что у клиента не должно быть никакой бизнес-логики, но поскольку вы не можете выполнять все вызовы параллельно, ваше веб-приложение будет предоставлять 9 методов, и эти методы на стороне сервера будут отвечать за вызов других функций веб-служб / БД и возвращать результат. Как я сказал в своем ответе, я не знаком с Websphere, возможно, эти асинхронные bean-компоненты - лучшее решение. - person iruediger; 14.06.2011