2013-11-23 2 views
1

Каковы рекомендации сообщества/советы по настройке в Java пула http-соединений для поддержки огромного количества одновременных HTTP-вызовов на одном сервере? Я имею в виду:Оптимизация соединения пула Java

  • макс Всего соединения
  • соединение макс по умолчанию на маршрут
  • стратегия повторного использования
  • поддерживать стратегию
  • поддерживать ДлИтЕлЬНОСтЬ
  • тайм-аут соединения
  • ....

(я использую компоненты HTTP Apache 4.3, но я доступен, чтобы исследовать новые решения)

Для того, чтобы быть более ясным, это моя ситуация:

Я разработал REST ресурс, который необходимо выполнить около 10 http вызывает AWS CloudSearch, чтобы получить результаты поиска, которые будут собраны в конечном результате (что я действительно не могу получить по одному запросу). Вся операция должна занимать менее 0,25 секунды. Итак, я запускаю http-вызовы параллельно в 10 разных потоках. Во время теста на скамью, я заметил, что с небольшим количеством одновременных запросов, 5, моя цель достигнута. Но, увеличивая одновременные запросы до 30, наблюдается огромная деградация производительности из-за времени соединения, которое занимает около 1 секунды. При одновременном использовании нескольких одновременных запросов время соединения составляет около 150 мс (точнее, первое соединение занимает 1 секунду, все следующие соединения занимают около 150 мс). Я могу гарантировать, что CloudSearch вернет свой ответ менее чем за 15 мс, поэтому в моем пуле подключений есть проблема.

Спасибо!

ответ

2

Количество потоков/соединений, которые являются лучшими для вашей реализации зависит от того осуществления (которые вы не отправляли), но вот некоторые рекомендации по запросу:

  • Если эти потоки не блокируют вообще , вы должны иметь столько потоков, сколько ядер (Runtime.availableCores(), это будет включать в себя гипертекстовые ядра). Просто потому, что использование более 100% CPU невозможно.

  • Если ваши потоки редко блокируются, сердечники * 2 - хорошее начало для бенчмаркинга.

  • Если ваши потоки часто блокируются, вам абсолютно необходимо сравнить приложение с различными настройками, чтобы найти лучшее решение для вашей реализации, ОС и оборудования.

Теперь самый оптимальный случай, очевидно, первый один, но, чтобы добраться до этого, вам необходимо удалить блокирование из кода столько, сколько вы можете. Java может сделать это для операций ввода-вывода, если вы используете пакет NIO в неблокирующем режиме (это не то, как это делает пакет Apache).

Затем у вас есть 1 поток, который ждет селектора и просыпается, как только любые данные будут готовы к отправке или чтению. Этот поток затем копирует только данные из своего источника в пункт назначения и возвращается к селектору. В случае чтения (входящих данных) это место назначения является блокирующей очередью, на которой ядро ​​ количество потоков.Один из этих потоков затем вытащит полученные данные и обработает их, теперь без каких-либо блокировок.

Затем вы можете использовать длину очереди блокировки, чтобы настроить количество параллельных запросов для вашей задачи и оборудования.


Первое соединение занимает> 1 секунду, так как оно фактически должно искать адрес через DNS. На данный момент все другие соединения приостановлены, так как нет смысла делать это дважды. Вы можете обойти это, вызвав IP-адрес (возможно, не очень хорошо, если вы поговорите с балансировщиком нагрузки) или путем «разогрева» соединений с первоначальным запросом. Любое новое соединение впоследствии будет использовать результат кэшированного DNS, но все равно необходимо выполнить другие инициализации, поэтому повторное использование соединений настолько сильно, насколько возможно, позволит значительно сократить время ожидания. С NIO это очень простая задача.

Кроме того, есть HTTP-multi-requests, то есть: вы делаете одно соединение, но запрашиваете несколько URL-адресов в одном запросе и получаете несколько ответов по «той же строке». Это значительно уменьшает накладные расходы на соединение, но требует поддержки сервера.

Смежные вопросы