Один порт для нескольких воркеров phpDaemon
Сегодня разбирались с демонизацией Zend Framework приложения на базе phpDaemon. При тестировании возникла одна проблема – при старте демона и обработке запроса на одном порту мог висеть только один демон.При увеличении параметров max-workers и start-workers вылетали ошибки вида “Couldn’t bind TCP-socket”. Пробовали вариант с созданием нескольких демонов на разных портах и балансировкой их через nginx. Вариант рабочий, но всё равно на порту сидел только один демон.
Всё дело в том, что демон может открывать блокирующий или неблокирующий сокет, в первом случае на нём висит только один воркер, а во втором – сколько угодно. Сделать сокет неблокирующим можно командой socket_set_nonblock($socket) или использую параметр SO_REUSEPORT при создании сокета. В phpdaemon это делается следующей строкой:
1 |
socket_set_option($sock, SOL_SOCKET, SO_REUSEPORT, 1) |
Факт выбора типа сокета (блокирующий/неблокирующий) задается глобальным параметром демона Daemon::$reusePort.
Потом ко мне попала инсайдерская информация, что успеха можно достичь добавив параметр priveleged в конфиг файл. И действительно, после этого при тестировании через ab (Apache Benchmark) в консоле появилась надпись (Spawn 10 workers).
Вот пример рабочего конфига для phpDaemon :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# Current file: # /etc/phpd/phpd.conf user www-data; group www-data; max-workers 10; min-workers 10; start-workers 2; max-requests 1m; max-idle 0; FastCGI { enable 1; listen-port 8091; listen 127.0.0.1; privileged; responder "Example"; } include conf.d/*.conf; |