502 ошибки шлюза при высокой нагрузке (nginx / php-fpm) - PullRequest
43 голосов
/ 07 января 2012

Я работаю на довольно загруженном интернет-сайте, который часто получает очень большие всплески трафика. Во время этих пиков запрашиваются сотни страниц в секунду, и это приводит к случайным ошибкам 502 шлюза.

Теперь мы запускаем Nginx (1.0.10) и PHP-FPM на машине с 4-мя накопителями SAS 15k (raid10) с 16-ядерным процессором и 24 ГБ оперативной памяти DDR3. Также мы используем последнюю версию Xcache. БД находится на другом компьютере, но загрузка этого компьютера очень низкая и проблем нет.

При нормальной нагрузке все работает отлично, загрузка системы ниже 1, а отчет о состоянии PHP-FPM никогда не показывает более 10 активных процессов одновременно. Всегда доступно около 10 ГБ оперативной памяти. При нормальной нагрузке машина обрабатывает около 100 просмотров страниц в секунду.

Проблема возникает, когда поступают огромные пики трафика, и с машины запрашивается сотни просмотров страниц в секунду. Я заметил, что в отчете о состоянии FPM отображается до 50 активных процессов, но это все еще намного ниже 300 максимальных подключений, которые мы настроили. Во время этих всплесков Nginx сообщает о 5000 активных подключений вместо обычного среднего значения 1000.

Информация об ОС: CentOS выпуск 5.7 (финальный)

Процессор: процессор Intel (R) Xeon (R) E5620 @ 2,40 ГГц (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 Socket.

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

limits.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 ]

24 голосов
/ 14 марта 2012

Это должно это исправить ...

У вас есть: fastcgi_buffers 4 256k;

Измените его на: fastcgi_buffers 256 16k; // 4096k всего

Также установите fastcgi_max_temp_file_size 0 , что отключит буферизацию на диск, если ответы начнут превышать ваши буферы fastcgi.

21 голосов
/ 30 августа 2012

Unix сокет принимает 128 соединений по умолчанию. Хорошо поставить эту строку в /etc/sysctl.conf

net.core.somaxconn = 4096
1 голос
/ 23 мая 2012

Если это не помогает в некоторых случаях - используйте обычную привязку порта вместо сокета, потому что сокет на 300+ может блокировать новые запросы, заставляя nginx показывать 502.

0 голосов
/ 22 апреля 2016

@ Mr. Бун

У меня 8 основных 14 ГБ оперативной памяти. Но система очень часто дает шлюзу время ожидания.
Реализация нижеприведенного исправления также не решила проблему. Все еще в поисках лучших исправлений.

У вас есть: fastcgi_buffers 4 256k;

Измените его на:

fastcgi_buffers 256 16k; // всего 4096k

Также установите fastcgi_max_temp_file_size 0, , который отключит буферизацию на диск, если ответы начнут превышать ваши fastcgi буферы.

Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...