Я хочу понять некоторые проблемы с производительностью сервера, которые я наблюдаю с (для нас) сильно загруженным веб-сервером. Среда выглядит следующим образом:
Поведение, которое мы наблюдаем, заключается в том, что Интернет обычно реагирует на запросы, но с небольшой задержкой для начала обработки запроса - иногда доли секунды, иногда 2-3 секунды в наше пиковое время использования. Фактическая нагрузка на сервер сообщается как очень высокая - часто 10.xx или 20.xx, как сообщает top
. Кроме того, в это время на сервере работают другие вещи (даже vi
) очень медленно, так что нагрузка определенно высока. Как ни странно, Apache остается очень отзывчивым, за исключением этой начальной задержки.
У нас Apache настроен следующим образом с использованием prefork:
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
И KeepAlive как:
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
Глядя на страницу состояния сервера, даже в эти периоды большой нагрузки мы редко достигаем лимита клиента, обычно обслуживая от 80 до 100 запросов, и многие из них находятся в состоянии keepalive. Это говорит мне исключить медлительность начального запроса как «ожидание обработчика», но я могу ошибаться.
Мониторинг Amazon CloudWatch говорит мне, что даже когда наша ОС сообщает о загрузке> 15, загрузка ЦП нашего экземпляра составляет 75-80%.
Пример вывода из top
:
top - 15:47:06 up 31 days, 1:38, 8 users, load average: 11.46, 7.10, 6.56
Tasks: 221 total, 28 running, 193 sleeping, 0 stopped, 0 zombie
Cpu(s): 66.9%us, 22.1%sy, 0.0%ni, 2.6%id, 3.1%wa, 0.0%hi, 0.7%si, 4.5%st
Mem: 7871900k total, 7850624k used, 21276k free, 68728k buffers
Swap: 0k total, 0k used, 0k free, 3750664k cached
Большинство процессов выглядит так:
24720 www-data 15 0 202m 26m 4412 S 9 0.3 0:02.97 apache2
24530 www-data 15 0 212m 35m 4544 S 7 0.5 0:03.05 apache2
24846 www-data 15 0 209m 33m 4420 S 7 0.4 0:01.03 apache2
24083 www-data 15 0 211m 35m 4484 S 7 0.5 0:07.14 apache2
24615 www-data 15 0 212m 35m 4404 S 7 0.5 0:02.89 apache2
Пример вывода из vmstat
в то же время, что и выше:
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
8 0 0 215084 68908 3774864 0 0 154 228 5 7 32 12 42 9
6 21 0 198948 68936 3775740 0 0 676 2363 4022 1047 56 16 9 15
23 0 0 169460 68936 3776356 0 0 432 1372 3762 835 76 21 0 0
23 1 0 140412 68936 3776648 0 0 280 0 3157 827 70 25 0 0
20 1 0 115892 68936 3776792 0 0 188 8 2802 532 68 24 0 0
6 1 0 133368 68936 3777780 0 0 752 71 3501 878 67 29 0 1
0 1 0 146656 68944 3778064 0 0 308 2052 3312 850 38 17 19 24
2 0 0 202104 68952 3778140 0 0 28 90 2617 700 44 13 33 5
9 0 0 188960 68956 3778200 0 0 8 0 2226 475 59 17 6 2
3 0 0 166364 68956 3778252 0 0 0 21 2288 386 65 19 1 0
И, наконец, вывод из Apache server-status
:
Server uptime: 31 days 2 hours 18 minutes 31 seconds
Total accesses: 60102946 - Total Traffic: 974.5 GB
CPU Usage: u209.62 s75.19 cu0 cs0 - .0106% CPU load
22.4 requests/sec - 380.3 kB/second - 17.0 kB/request
107 requests currently being processed, 6 idle workers
C.KKKW..KWWKKWKW.KKKCKK..KKK.KKKK.KK._WK.K.K.KKKKK.K.R.KK..C.C.K
K.C.K..WK_K..KKW_CK.WK..W.KKKWKCKCKW.W_KKKKK.KKWKKKW._KKK.CKK...
KK_KWKKKWKCKCWKK.KKKCK..........................................
................................................................
Исходя из моего ограниченного опыта, я делаю следующие выводы / вопросы:
Мы можем позволить слишком много KeepAlive
Запросы
Я действительно вижу некоторое время, потраченное на ожидание ввода-вывода в vmstat, хотя не постоянно и не очень много (я думаю?), Поэтому я не уверен, что это большая проблема или нет, я менее опытен с vmstat
Также в vmstat я вижу в некоторых итерациях ряд процессов, ожидающих обслуживания, и это то, чему я приписываю задержку начальной загрузки страницы на нашем веб-сервере, возможно, ошибочно
Мы обслуживаем смесь статического содержимого (75% или выше) и содержимого сценария, и содержимое сценария часто требует значительных затрат процессора, поэтому важно найти правильный баланс между ними; в долгосрочной перспективе мы хотим переместить статику в другое место, чтобы оптимизировать оба сервера, но сегодня наше программное обеспечение не готово к этому
Я рад предоставить дополнительную информацию, если у кого-то есть какие-либо идеи, другое примечание заключается в том, что это производственная установка с высокой доступностью, поэтому я с осторожностью отношусь к настройке за настройкой, и поэтому я не играл с такими вещами, как KeepAlive
пока себя ценю.
Я начну с признания, что я не очень люблю запускать что-то в облаках, но, основываясь на моем опыте в другом месте, я бы сказал, что эта конфигурация веб-сервера отражает довольно низкий объем трафика. То, что очередь выполнения настолько велика, говорит о том, что для работы с ней просто недостаточно ЦП. Что еще в очереди?
Возможно, мы разрешаем слишком много запросов KeepAlive
Нет - keeplive по-прежнему повышает производительность, современные браузеры очень умны, зная, когда выполнять конвейерную обработку, а когда запускать запросы параллельно, хотя тайм-аут в 5 секунд все еще довольно велик, и у вас есть МНОГО серверов, ожидающих - если у вас нет ОГРОМНЫХ проблем с задержкой, я бы рекомендовал уменьшить это значение до 2-3. Это должно немного сократить очередь выполнения.
Если вы еще не установили mod_deflate на веб-сервере - я бы рекомендовал вам сделать это - и добавить ob_gzhandler () в свои сценарии PHP. Вы можете сделать это автоматически:
if(!ob_start("ob_gzhandler")) ob_start();
(да, сжатие использует больше ЦП, но вы должны сэкономить ЦП в целом, быстрее выводя серверы из очереди выполнения / обрабатывая меньше TCP-пакетов - и в качестве бонуса ваш сайт также работает быстрее).
Я бы рекомендовал установить верхний предел для MaxRequestsPerChild - скажем, 500. Это просто позволяет некоторый оборот процессов в случае, если у вас где-то есть утечка памяти. Ваши процессы httpd выглядят ОГРОМНЫМИ - убедитесь, что вы удалили все модули apache, которые вам не нужны, и убедитесь, что вы обслуживаете статический контент с хорошей информацией кеширования.
Если вы все еще видите проблемы, то проблема, вероятно, связана с кодом PHP (если вы переключитесь на использование fastCGI, это должно быть очевидно без какого-либо серьезного снижения производительности).
Обновить
Если статическое содержимое не сильно различается на разных страницах, возможно, стоит поэкспериментировать с:
if (count($_COOKIE)) {
header('Connection: close');
}
на скриптах PHP тоже.
Вам следует подумать об установке асинхронного обратного прокси-сервера, поскольку количество процессов в состоянии W также довольно велико. Ваши процессы Apache, похоже, тратят много времени на отправку контента медленным клиентам по сети, которая блокируется на этом. Nginx или lighttpd в качестве интерфейса для вашего сервера Apache может значительно сократить количество процессов в состоянии W. И да, вы должны ограничить количество запросов keepalive. Наверное, стоит попробовать отключить поддержку активности.
Кстати, 107 процессов Apache слишком высоки для 22 rps, я смог обслужить 100-120 rps, используя только 5 процессов Apache. Вероятно, следующим шагом будет профилирование вашего приложения.
У вас есть две строки в вашем vmstat, которые показывают, что время ожидания вашего процессора довольно велико, и вокруг них вы выполняете изрядное количество операций записи (io-bo) и переключения контекста. Я бы посмотрел, что пишет блоки и как избавиться от этого ожидания. Я думаю, что наибольшее улучшение можно найти в улучшении ввода-вывода вашего диска. Проверьте системный журнал - установите для него запись async. Убедитесь, что кеш записи вашего контроллера работает (проверьте его - возможно, у вас плохой аккумулятор).
Keepalive не вызывает проблем с перфомансом, он экономит ваше время на настройку соединения, если вы не запускаете кеш на переднем плане. Вы можете немного поднять MaxSpareServers, чтобы в случае кризиса вам не пришлось ждать всех вилок.
Первое предложение: отключить сообщения поддержки активности. Мне он когда-либо понадобился только тогда, когда я мог определить конкретную ситуацию, когда производительность увеличилась, но в целом количество запросов в секунду уменьшилось при включенном Keepalive.
Второе предложение: установите MaxRequestsPerChild. Я повторяю здесь symcbean, это поможет с опрокидыванием процесса в случае утечки памяти. 500 - хорошая отправная точка.
Третье предложение: увеличьте количество клиентов MaxClients. Примерный расчет для этого: (физическая память - память, используемая процессом, отличным от httpd) / размер каждого процесса httpd. В зависимости от того, как был скомпилирован httpd, это число максимально равно 255. Я использую 250 для своих общедоступных серверов, чтобы иметь дело с google / yahoo / MS, сканирующими системы.
Четвертое предложение: Увеличьте MaxSpareServers: что-то вроде 4-5x MinSpareServers.
Если эти предложения терпят неудачу, я бы посмотрел на балансировку нагрузки с помощью обратного прокси или кэша памяти для БД.
вам следует подумать об отключении поддержки активности в качестве первой попытки ...
со 107 обработанными запросами я бы держал MaxSpareServers выше, чем вы установили ...
IMHO в долгосрочной перспективе nginx как обратный прокси для статического контента следует учитывать