502 ошибки шлюза при высокой нагрузке (nginx / php-fpm)
Я работаю на довольно оживленной интернет-сайт, который часто получает очень большие всплески трафика. Во время этих всплесков запрашиваются сотни страниц в секунду, и это приводит к случайным ошибкам шлюза 502.
теперь мы запускаем Nginx (1.0.10) и PHP-FPM на машине с 4x SAS 15K дисками (raid10) с 16-ядерным процессором и 24 ГБ оперативной памяти DDR3. Также мы используем последнюю версию Xcache. DB расположен на другой машине, но нагрузка этой машины очень низка, и не имеет никакой проблемы.
при нормальной загрузке все работает идеально, загрузка системы ниже 1, а отчет о состоянии PHP-FPM никогда не показывает более 10 активных процессов одновременно. Всегда доступно около 10GB ОЗУ. При нормальной нагрузке машина обрабатывает около 100 страниц в секунду.
проблема возникает, когда огромные всплески трафика приехать, и сотни просмотра страниц в секунду запрашиваются с компьютера. Я заметил, что отчет о состоянии FPM затем отображается до 50 активных процессов, но это все еще намного ниже 300 максимальных подключений, которые мы настроили. Во время этих всплесков nginx сообщает о состоянии до 5000 активных соединений вместо обычного среднего значения 1000.
информация об ОС: CentOS release 5.7 (Final)
CPU: Intel(R) Xeon (R) CPU E5620 @ 2.40 GH (16 ядер)
php-fpm.conf
daemonize = yes
listen = /tmp/fpm.sock
pm = static
pm.max_children = 300
pm.max_requests = 1000
Я не настраивал rlimit_files, потому что, насколько я знаю, он должен использовать по умолчанию, если вы не.
fastcgi_params (добавлены только значения в стандартный файл)
fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;
fastcgi_pass unix:/tmp/fpm.sock;
nginx.conf
worker_processes 8;
worker_connections 16384;
sendfile on;
tcp_nopush on;
keepalive_timeout 4;
Nginx подключается к FPM через сокет Unix.
sysctl-переменной.conf
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 1
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.tcp_timestamps = 0
net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.default.rp_filter=1
net.ipv4.conf.eth0.rp_filter=1
net.ipv4.conf.lo.rp_filter=1
net.ipv4.ip_conntrack_max = 100000
ограничения.conf
* soft nofile 65536
* hard nofile 65536
это результаты для следующих команд:
ulimit -n
65536
ulimit -Sn
65536
ulimit -Hn
65536
cat /proc/sys/fs/file-max
2390143
вопрос: если PHP-FPM не заканчиваются соединения, нагрузка все еще низкая, и есть много доступной оперативной памяти, какое узкое место может быть причиной этих случайных ошибок шлюза 502 во время высокого трафика?
примечание: по умолчанию ulimit этой машины были 1024, так как я изменил его на 65536, я не полностью перезагрузил машину, так как это производственная машина, и это означало бы слишком много времени простоя.
4 ответов
Это должно исправить...
У вас есть: fastcgi_buffers 4 256k;
изменить его: fastcgi_buffers 256 16k; // 4096к в общей сумме
и набор fastcgi_max_temp_file_size 0, это отключит буферизацию на диск, если ответы начнут выделять ваши буферы fastcgi.
сокет Unix принимает 128 соединений по умолчанию. Хорошо поставить эту строку в /etc/sysctl.conf
net.core.somaxconn = 4096
Если это не помогает в некоторых случаях-используйте обычную привязку порта вместо сокета, потому что сокет на 300+ может блокировать новые запросы, заставляя nginx показывать 502.
@Г-Н Боон
У меня есть 8 core 14 GB ram. Но система дает Gateway тайм-аут очень часто.
Реализация ниже fix также не решила проблему. Все еще ищу лучшие исправления.
у вас есть: fastcgi_buffers 4 256k;
меняем его на:
fastcgi_buffers 256 16к; // 4096к в общей сумме
и набор fastcgi_max_temp_file_size 0, это отключит буферизацию на диск, если ответы начнут превышать fastcgi
буферов.
спасибо.