Я хочу использовать PHP для создания постоянного соединения сокетов на сервере службы уведомлений, и мне интересно, сколько потоков Apache / PHP могло бы одновременно использовать сокет, прежде чем у меня возникнут проблемы. Я провел некоторое тестирование с этим, но я не могу создать никаких проблем.
редактировать
Я использую сокет следующим образом:
$fh = pfsockopen('127.0.0.1', '1338'); fwrite($fh,$data);
Каждый поток PHP будет иметь один и тот же постоянный сокет
Ограничение с помощью fsockopen
– это максимальное количество дескрипторов открытых файлов, определенных в настройках ядра системы. Если pfsockopen
хорошо реализован, он должен использовать только одно соединение сокета, означает только один дескриптор файла для каждого процесса php .
Тебе придется протестировать это.
например
$fd = pfsockopen('173.194.44.24', 80); echo $fd;
Это выведет идентификатор файлового дескриптора: Resource id #1
Откройте это в веб-браузере и перезагрузите страницу несколько раз – вы должны увидеть один и тот же идентификатор каждый раз, когда используете одно и то же соединение сокета.
В стандартной настройке Apache prefork MPM – mod_php вы, вероятно, произвольно отправляются в разные разветвленные процессы, которые, скорее всего, приведут к прохождению n разных идентификаторов, в то время как n зависит от вашей конфигурации Apache
MinSpareServers
(<= n pConnections) MaxSpareServers
(> = n pConnections) MaxRequestsPerChild
(tMax) Когда вы достигаете MaxRequestsPerChild
процесс прекращается и постоянное соединение с этим ребенком.
В Apache Worker MPM или любом другом веб-сервере, поддерживающем fastcgi, например Lighttpd или Nginx, в сочетании с PHP-FPM или PHP-cgi + fastcgi, я ожидаю такого же поведения, которое теперь не вызвано веб-сервером, а процессами php.
Параллельно с настройками apache, описанными выше, соответствующие настройки
PHP-FPM
pm.min_spare_servers
(<= n pConnections) pm.max_spare_servers
(> = n pConnections) pm.max_requests
(tMax) FastCGI
PHP_FCGI_CHILDREN
(= n pConnections) PHP_FCGI_MAX_REQUESTS
(tMax) Во всех конфигурациях максимальное время жизни постоянного соединения (в количестве запросов, обрабатываемых этим процессом) tMax
, максимальное количество параллельных постоянных подключений n pConnections
Имитируя это в командной строке (php-cli)
# php -a Interactive shell # in a webserver environment this is the equivalent of one child php > $fd1 = fsockopen( 'google.de', 80 ); # open non-persistent connection php > echo $fd1 . "\n"; Resource id #1 php > $fd2 = fsockopen( 'google.de', 80 ); # open another one php > echo $fd2 . "\n"; Resource id #2 # new fd, new connection php > $pd1 = pfsockopen( 'google.de', 80 ); # persistent connection php > echo $pd1 . "\n"; Resource id #3 # first persistent fd php > $pd2 = pfsockopen( 'google.de', 80 ); php > echo $pd2 . "\n"; Resource id #3 # uses the same connection php > exit # simulating MaxRequestsPerChild threshold # php -a Interactive shell php > $pd3 = pfsockopen( 'google.de', 80 ); # persistent connection, same host php > echo $pd3 . "\n"; Resource id #1 # resource id reused because all old connections are gone
РЕДАКТИРОВАТЬ
На самом деле я забыл упомянуть о втором ограничении. Разумеется, соединения могут быть закрыты в любое время самим сервером. Это сильно зависит от настроек сервера и протокола, который вы используете.
Большинство серверов закрывают соединение через n
секунд молчания и через x
секунд общего времени соединения.
pconnect
обрабатывает это тихо, он просто открывает новое соединение, когда старый ушел.
Имитируя это снова на cli:
# php -a Interactive shell php > $pd1 = pfsockopen( '127.0.0.1', 80 ); php > echo $pd1 . "\n"; Resource id #1 php > $pd1 = pfsockopen( '127.0.0.1', 80 ); php > echo $pd1 . "\n"; Resource id #1 (restarting my webserver on the another console /etc/init.d/nginx restart) php > $pd1 = pfsockopen( '127.0.0.1', 80 ); php > echo $pd1 . "\n"; Resource id #2