Как определить наилучшее количество потоков в Tomcat?

StackOverflow https://stackoverflow.com/questions/1286446

  •  18-09-2019
  •  | 
  •  

Вопрос

Как определить наилучшее количество maxSpare, minSpare и maxThreads, AcceptCount и т. д. в Tomcat?Существуют ли существующие лучшие практики?

Я понимаю, что это должно быть основано на аппаратном обеспечении (например,на ядро) и может служить лишь основой для дальнейшего тестирования производительности и оптимизации на конкретном оборудовании.

Это было полезно?

Решение

«Проблема количества потоков» — довольно большая и сложная проблема, на которую невозможно ответить с помощью простого эмпирического правила.

Учитывать, сколько у вас ядер, полезно для многопоточных приложений, которые, как правило, потребляют много ресурсов ЦП, таких как обработка чисел и тому подобное.Это редко случается с веб-приложением, которое обычно перегружается не процессором, а другими факторами.

Одним из распространенных ограничений является задержка между вами и другими внешними системами, особенно вашей БД.Каждый раз, когда поступает запрос, он, вероятно, будет несколько раз запрашивать базу данных, что означает потоковую передачу некоторых байтов через соединение JDBC, а затем ожидание поступления этих байтов в базу данных (даже если он находится на локальном хосте, все равно есть небольшая задержка). , затем ждем, пока БД рассмотрит наш запрос, затем ждем, пока база данных его обработает (база сама будет ждать, пока диск перейдет в определенный регион) и т.д...

Все это время поток простаивает, поэтому другой поток может легко использовать ресурсы ЦП для выполнения чего-нибудь полезного.Довольно часто можно увидеть, что от 40% до 80% времени тратится на ожидание ответа БД.

То же самое происходит и на другой стороне соединения.Пока ваш поток записывает свои выходные данные в браузер, скорость соединения КЛИЕНТА может привести к тому, что ваш поток будет простаивать, ожидая, пока браузер подтвердит, что определенный пакет был получен.(Несколько лет назад это было серьезной проблемой, последние ядра и JVM используют буферы большего размера, чтобы предотвратить холостой ход ваших потоков, однако обратный прокси-сервер перед вашим сервером веб-приложений, даже просто httpd, может быть действительно полезен, чтобы избежать людей с плохим подключением к Интернету действовать как DDOS-атака :) )

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

Итак, что же ограничивает количество потоков, которые вы можете настроить?

Прежде всего, каждый поток (раньше) потреблял много ресурсов.У каждого потока есть стек, который потребляет ОЗУ.Более того, каждый поток фактически выделяет материал в куче для выполнения своей работы, снова потребляя ОЗУ, а процесс переключения между потоками (переключение контекста) довольно тяжел для ядра JVM/OS.

Это затрудняет «плавную» работу сервера с тысячами потоков.

Учитывая эту картину, существует ряд техник (в основном:попробуйте, потерпите неудачу, настройте, попробуйте еще раз), чтобы более или менее определить, сколько потоков понадобится вашему приложению:

1) Постарайтесь понять, где ваши темы проводят время.Существует ряд хороших инструментов, но даже профилировщик jvisualvm может быть отличным инструментом или средством отслеживания, которое производит сводную статистику времени.Чем больше времени они тратят на ожидание чего-то внешнего, тем больше вы можете создать больше потоков, которые будут использовать ЦП во время простоя.

2) Определите использование оперативной памяти.Учитывая, что JVM будет использовать определенный объем памяти (особенно пространство Permgen, обычно до ста мегабайт, опять же jvisualvm подскажет) независимо от того, сколько потоков вы используете, попробуйте запустить с одним потоком, затем с десятью, а затем с сто, загружая приложение с помощью jmeter или чего-то еще, и посмотрите, как вырастет использование кучи.Это может стать жестким ограничением.

3) Попробуйте определить цель.Каждый пользовательский запрос требует обработки потока.Если ваше среднее время ответа составляет 200 мс на «получение» (лучше не учитывать загрузку изображений, CSS и других статических ресурсов), то каждый поток способен обслуживать 4/5 страниц в секунду.Если ожидается, что каждый пользователь будет «щелкать» каждые 3/4 секунды (зависит от того, браузерная ли это игра или сайт с большим количеством длинных текстов?), то один поток будет «обслуживать 20 одновременных пользователей», что бы это ни значило.Если в час пик на ваш сайт за 1 минуту заходит 500 одиночных пользователей, то вам нужно достаточно потоков, чтобы справиться с этим.

4) Краш-тест верхнего предела.Используйте jmeter, настройте сервер с большим количеством потоков на запасной виртуальной машине и посмотрите, как ухудшится время отклика, если вы превысите определенный предел.Здесь важна не только аппаратная реализация потоков базовой ОС, но независимо от того, что произойдет, ЦП будет тратить больше времени на то, чтобы выяснить, какой поток запускать, чем на его выполнение на самом деле, и это число не так уж и невероятно. высокий.

5) Подумайте, как потоки повлияют на другие компоненты.Каждый поток, вероятно, будет использовать одно (или, возможно, более одного) соединение с базой данных. Может ли база данных обрабатывать 50/100/500 одновременных подключений?Даже если вы используете сегментированный кластер серверов nosql, обеспечивает ли ферма серверов достаточную пропускную способность между этими компьютерами?Что еще будет работать на одной машине с сервером веб-приложений?Аначе httpd?кальмар?сама база данных?локальный прокси-сервер кэширования для базы данных, например mongos или memcached?

Я видел работающие системы только с 4 потоками + 4 запасными потоками, потому что работа, выполняемая этим сервером, заключалась просто в изменении размера изображений, поэтому он почти на 100% загружал процессор, а другие были настроены на более или менее таком же оборудовании с пару сотен потоков, потому что веб-приложение выполняло множество вызовов SOAP к внешним системам и тратило большую часть времени на ожидание ответов.

Итак, вы определили приблизительное значение.минимальный и максимальный потоки, оптимальные для вашего веб-приложения, обычно я настраиваю его следующим образом:

1) Исходя из ограничений оперативной памяти, других внешних ресурсов и экспериментов по переключению контекста, существует абсолютный максимум, которого нельзя достигать.Итак, используйте maxThreads, чтобы ограничить его примерно половиной или 3/4 этого числа.

2) Если приложение достаточно быстрое (например, оно предоставляет веб-службы REST, которые обычно отправляют ответ в течение нескольких миллисекунд), то вы можете настроить большое значение AcceptCount, вплоть до такого же количества maxThreads.Если у вас есть балансировщик нагрузки перед сервером веб-приложений, установите небольшой параметр AcceptCount. Лучше, чтобы балансировщик нагрузки увидел непринятые запросы и переключился на другой сервер, чем приостанавливал пользователей на уже занятом сервере.

3) Поскольку запуск потока (по-прежнему) считается тяжелой операцией, используйте minSpareThreads, чтобы подготовить несколько потоков к наступлению часов пик.Это опять же зависит от типа нагрузки, которую вы ожидаете.Даже разумно настроить minSpareThreads, maxSpareThreads и maxThreads, чтобы точное количество потоков всегда было готово, никогда не освобождалось, а производительность была предсказуемой.Если вы используете tomcat на выделенном компьютере, вы можете поднять minSpareThreads и maxSpareThreads без какой-либо опасности перегрузить другие процессы, в противном случае настройте их, поскольку потоки — это ресурсы, совместно используемые с остальными процессами, работающими в большинстве ОС.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top