2009-08-17 4 views
21

Как определить максимальное количество maxSpare, minSpire и maxThreads, acceptCount и т. Д. В Tomcat? Являются ли существующие передовые методы?Как определить максимальное количество потоков в Tomcat?

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

ответ

46

«сколько проблем с резьбой» является довольно большой и сложной проблемой, и на него нельзя ответить простым простым правилом.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Oce вы определили ок. минимальные и максимальные потоки, оптимальные для вас, webapp, тогда я обычно настраиваю его таким образом:

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

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

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