В настоящее время я запускаю веб-приложение, которое видит, как несколько (~ 15) пользователей входят в систему один раз в день, а затем оставляют веб-приложение открытым, где оно автоматически обновляется новым контентом каждые 5 минут. Каждый пользователь имеет тенденцию держать его открытым около 15-18 часов.
Однако при критической массе (~ 30-40) пользователей все начинает резко замедляться, и процесс HTTPD начинает увеличиваться в использовании памяти. Я добавил задание cron, которое перезапускает apache один раз в час, но это помогает лишь частично. Весь контент генерируется динамически и новое время, поэтому кеширование страниц невозможно.
Я начал экспериментировать с параметрами Timeout, MaxRequest и KeepAlive, но я буду очень признателен за любые рекомендации, так как в прошлом я всегда оставлял их по умолчанию.
Вот что у меня есть. У каких-нибудь гениев apache есть идеи, как оптимизировать эту конфигурацию для вышеуказанного сценария? Я решил, что длительный тайм-аут - это хорошо, потому что время загрузки иногда может быть ОЧЕНЬ большим.
# Timeout: The number of seconds before receives and sends time out.
Timeout 200
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
KeepAlive On
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
MaxKeepAliveRequests 100
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
KeepAliveTimeout 60
# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# ServerLimit: maximum value for MaxClients for the lifetime of the server
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule prefork.c>
StartServers 16
MinSpareServers 10
MaxSpareServers 20
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000
</IfModule>
Я думаю, тебе нужно поиграть с MaxRequestsPerChild директива. Перезапуск apache каждый час не кажется мне изящным решением. MaxRequestsPerChild каждый процесс автоматически перезапускается после того, как он обслужит заданное количество запросов. Попробуй установить на 100?
Также можно использовать гораздо более легкий веб-сервер (например, nginx) для кормления медленных клиентов и обслуживания статических носителей снимет большую нагрузку с apache.
(Я упростил числа для ясности, особенно часть памяти слишком велика)
Ваш MaxRequestsPerChild в настоящее время составляет 4000, учитывая, что вы получаете 50 пользователей в день, которые каждый обновляет каждые 5 минут в течение 18 часов, что составляет 600 запросов в час и 10800 запросов в день. Для справки, один пользователь использует 218 подключений в день.
Это означает, что дочерние процессы перезапускаются 2,7 раза в день. Если ваше приложение использует 50 МБ памяти на перезагрузку и ему удается освободить из них 49 МБ, 1 МБ за обновление, 50 МБ для 50 пользователей и 4G для 4000 перезагрузок. И ребенок будет убит.
Вы должны проверить, сколько памяти использует ваше приложение, и установить эти значения в соответствии с ними.
Если ваш сервер имеет 20 ГБ памяти, эта утечка 1 МБ будет работать в некоторой степени, но изменение MaxRequestsPerChild, например, на 1000 уменьшит потребление памяти перед перезапуском дочернего элемента в четыре раза.
В качестве примечания, вы можете уменьшить MaxClients примерно до 100 и убедиться, что на самом деле не так много пользователей, как вы думаете. Таким образом, случайные проблемы не приведут к отказу сервера от слишком большого количества запросов. Продолжительность KeepAliveTimeout может составлять примерно 15 секунд, поскольку пользователи обновляются только каждые 5 минут.