I am wanting to use PHP to create a persistent socket connection to a notification service server and I am wondering how many Apache/PHP threads would be able to concurrently use the socket before I have problems. I have done some testing with this but I cannot seem to produce any problems.
Edit
I am using the socket like this:
$fh = pfsockopen('127.0.0.1', '1338');
fwrite($fh,$data);
Every PHP thread would share the same persistent socket
The limitation with fsockopen
is the maximum amount of open file descriptors defined in the systems kernel settings. If pfsockopen
is implemented well, it should only use one single socket connection, means only one file descriptor per php process.
You'll have to test this.
e.g.
$fd = pfsockopen('173.194.44.24', 80);
echo $fd;
This will output the id of the file descriptor: Resource id #1
Open this in a web browser and reload the page several times - you should see the same id each time you are using the same socket connection.
In a default Apache prefork MPM - mod_php setup you probably are randomly sent to different forked processes which will most likely result in n different ids cycling through, while n depends on your Apache configuration of
MinSpareServers
(<= n pConnections)MaxSpareServers
(>= n pConnections)MaxRequestsPerChild
(tMax)When you reach MaxRequestsPerChild
the process is terminated and the persistent connection on this child as well.
In a Apache Worker MPM or any other fastcgi-capable webserver like Lighttpd or Nginx combined with PHP-FPM or PHP-cgi + fastcgi I am expecting the same behavior, now not caused by the webserver but by the php processes.
In parallel to the apache settings described above, the relevant settings are
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)In all configurations the maximum lifetime of a persistent connection is (in amount of requests handled by that process) tMax
, the max amount of parallel persistent connections n pConnections
Simulating this on the command-line (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
EDIT
Acually I forgot to mention a second limitation. Connections of course can be closed anytime by the server itself. This heavily depends on the server settings and protocol you are using.
Most servers close a connection after n
seconds of silence and after x
seconds of total connection time.
pfsockopen
handles this silently, it simply opens a new connection when the old one is gone.
Simulating this on cli again:
# 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With