Я хочу использовать 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