Назад | Перейти на главную страницу

Настройка производительности сервера Apache с высокой нагрузкой

Я хочу понять некоторые проблемы с производительностью сервера, которые я наблюдаю с (для нас) сильно загруженным веб-сервером. Среда выглядит следующим образом:

Поведение, которое мы наблюдаем, заключается в том, что Интернет обычно реагирует на запросы, но с небольшой задержкой для начала обработки запроса - иногда доли секунды, иногда 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 пока себя ценю.

Я начну с признания, что я не очень люблю запускать что-то в облаках, но, основываясь на моем опыте в другом месте, я бы сказал, что эта конфигурация веб-сервера отражает довольно низкий объем трафика. То, что очередь выполнения настолько велика, говорит о том, что для работы с ней просто недостаточно ЦП. Что еще в очереди?

Возможно, мы разрешаем слишком много запросов 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 как обратный прокси для статического контента следует учитывать