Читал много статей, в которых советовали использовать unix socket в связке nginx + php-fpm. Потом наткнулся на
эту статью: Решил проверить, что же лучше. Для тестов решил использовать ab и два файла, которые nginx будет отдавать:
- index.html со стандартным: It Works!
- phpinfo.php с содержимым: <?php phpinfo();
Имеем: Debian 6.0 с последними апдейтами и nginx 1.0.2 + php-fpm 5.3.6 (dotdeb). Сервер: HP DL140 (2 x Intel Xeon L5320, 16GB DDR3). php-fpm в static с max_children 1000
Тестирование:
- ab -c 20000 -n 100000 — Результат: Failed requests: 0
- ab -c 4000 -n 10000 — Результат: Failed requests: 5294 (unix socket)
- ab -c 4000 -n 10000 — Результат: Failed requests: 0 (tcp/ip)
Тем самым, согласно 1-у тесту, имеем доказательство, что nginx корректно обрабатывает 20000 конкурентных запросов и проблема не в нём. Следовательно дело в php-fpm и в типе его «подключения». Конечно, возможно, нужно потюнить ядро чтобы изменить ситуацию, но имея дефолтные настройки, почему php-fpm через unix socket так сильно проигрывает?
UPD1:
Увеличения значения параметра ядра net.core.somaxconn со 128 до 1024 (и даже 102400) незначительно повлияло на уменьшение fail до 4000-4500. Но до эталонного нуля, ещё далеко…
UPD2:
Изменение backlog как в ядре, так и в php-fpm результатов не дало. Оставил -1, но добавил 8 пулов php-fpm (по одому на каждое ядро), и установил у каждого max_children 500. Результаты впечатлили:
ab -c 7000 -n 7000 — Результат: Failed requests: 0
(unix socket)
Если завышать -c > 7000, то тестирование валится с ошибкой. Видимо, ограничение уже на уровне ядра. Хотя somaxconn, backlog > 10000. Далее решил погонять tcp/ip:
- ab -c 7000 -n 7000 — Результат: Failed requests: 0 (tcp/ip)
- ab -c 10000 -n 10000 — Результат: Failed requests: 225 (tcp/ip)
- ab -c 20000 -n 20000 — Результат: Failed requests: 733 (tcp/ip)
Вывод: получается, что tcp/ip пока лучше, т.к. выдерживает > 7000 конкурентных запросов.