Apache использует 100% CPU, но только часть оперативной памяти при большой нагрузке
Я использую веб-сайт, который интенсивно используется в определенное время. Я запускаю apache 2.4 на сервере EC2 Ubuntu 16.04 с 4-ядерным процессором, 16 ГБ оперативной памяти и 2 ГБ подкачки. Размер среднего процесса Apache составляет 35 МБ (приблизительно). Я установил для KeepAlive значение ON и KeepAliveTimeout для более низкого значения 5.
Я использую MPM prefork, и конфигурация выглядит следующим образом:
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
ServerLimit 350
MaxRequestWorkers 350
MaxConnectionsPerChild 20000
</IfModule>
Когда количество одновременно работающих пользователей увеличивается, htop показывает, что все 4 ядра используются на 100%, однако ОЗУ по-прежнему показывает только 1,5 или 2 ГБ из доступных 15 ГБ.
Почему не используется больше памяти? Нормально ли использовать такой процессор? Если отсюда увеличивается количество пользователей, сервер начинает возвращать ошибку HTTP 522.
Дополнительная информация: вычисления, используемые для получения значений, упоминались в этом руководстве и в этом ответе на ServerFault.
Я обнаружил, что один процесс Apache занимает около 35 МБ памяти. Я запускаю nodejs (для socketio) под PM2. MySQL запускается из RDS и не находится на этом сервере. Тем не менее, я уменьшил некоторые значения в соответствии с предлагаемыми расчетами:
Available Memory - 14000MB
(оставляя оставшуюся оперативную память для других целей)
Apache Process usage - 40MB
MaxRequestWorkers = 14000/40 = 350
StartServers 30% of MaxRequestWorkers
(должно быть 105, но я чувствую, что это слишком высоко. Должен ли я сделать это 105?)
MinSpareServers 5% of MaxRequestWorkers
(должно быть 17)
MaxSpareServers 10% of MaxClients
(Можно ли иметь это значение таким же, как StartServers и до 105?)
ServerLimit = MaxRequestWorkers
Изменить Я изменил конфигурацию prefork, используя предложенные расчеты:
<IfModule mpm_prefork_module>
StartServers 105
MinSpareServers 17
MaxSpareServers 105
ServerLimit 350
MaxRequestWorkers 350
MaxConnectionsPerChild 20000
</IfModule>
Я запустил скрипт, который выполняет 2 вызова API, имитируя входящего в систему пользователя и выполняя какое-то действие 4 раза. Выполнение 20 из этих сценариев параллельно с новыми конфигурациями по-прежнему давало среднее значение высокой нагрузки: