Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Whether the connection between php-fpm and nginx by fast-cgi are persistent (keep-alive) connection?

Tags:

php

nginx

sockets

I am trying to write a server demo to connect the php-fpm , but i don't know whether the connection between php-fpm and nginx by fast-cgi are persistent (keep-alive) connection? Every time when http request to nginx , will the nginx connect php-fpm by tcp 3-Way Handshake again ? Or the connection between nginx and php-fpm is a keep-alive connect and nginx try to reuse it ?

like image 527
Mattia Dinosaur Avatar asked Apr 07 '17 14:04

Mattia Dinosaur


2 Answers

PHP-FPM is an implementation of the fastCGI protocol, and as such it abides by all the fastCGI specification requirements.

One such requirement is in section 3.5 of the specification, specifically about Closing connections:

The Web server controls the lifetime of transport connections. The Web server can close a connection when no requests are active. Or the Web server can delegate close authority to the application (see FCGI_BEGIN_REQUEST). In this case the application closes the connection at the end of a specified request. This flexibility accommodates a variety of application styles. Simple applications will process one request at a time and accept a new transport connection for each request. More complex applications will process concurrent requests, over one or multiple transport connections, and will keep transport connections open for long periods of time.

A simple application gets a significant performance boost by closing the transport connection when it has finished writing its response. The Web server needs to control the connection lifetime for long-lived connections.

When an application closes a connection or finds that a connection has closed, the application initiates a new connection.

This means that it is up to the webserver to decide whether the connection will persist or not. This is implemented in nginx via the fastcgi_keep_conn option which states:

By default, a FastCGI server will close a connection right after sending the response. However, when this directive is set to the value on, nginx will instruct a FastCGI server to keep connections open. This is necessary, in particular, for keepalive connections to FastCGI servers to function.

This statement is to reflect the specification behaviour as well as the capability of the webserver that can serve fastCGI generated content to modify the default behaviour.

My assumption here is that there is no real point to keep connections alive since the threads of webservers are constantly recycled. Perhaps there's a specified number of parked threads but the usual policy of thread pooling is to kill the least recently used thread, usually this means that spawning a new thread will ensure that pre-exiting threads are the ones that get killed.

Admittedly I have found no resource to back up the claim that the pool collection policy of nginx is LRU but it's not unlikely that it is and in that case keeping the connection alive does not save much.

like image 160
apokryfos Avatar answered Oct 31 '22 13:10

apokryfos


After a years later i ask this question,i seem to find the answer.

(gdb) bt
#0  close () at ../sysdeps/unix/syscall-template.S:84
#1  0x0000000000a40dff in fcgi_close (req=0x1dae3c0, force=0, destroy=1) at /home/dinosaur/Downloads/php-7.2.2/main/fastcgi.c:1311
#2  0x0000000000a41a0d in fcgi_finish_request (req=0x1dae3c0, force_close=0) at /home/dinosaur/Downloads/php-7.2.2/main/fastcgi.c:1670
#3  0x0000000000a4d3b3 in sapi_cgi_deactivate () at /home/dinosaur/Downloads/php-7.2.2/sapi/fpm/fpm/fpm_main.c:828
#4  0x00000000008bcf35 in sapi_deactivate () at /home/dinosaur/Downloads/php-7.2.2/main/SAPI.c:532
#5  0x00000000008afa0e in php_request_shutdown (dummy=0x0) at /home/dinosaur/Downloads/php-7.2.2/main/main.c:1913
#6  0x0000000000a50614 in main (argc=1, argv=0x7ffc8b6936e8) at /home/dinosaur/Downloads/php-7.2.2/sapi/fpm/fpm/fpm_main.c:1994

when the php-fpm start ,after init, it while loop to deal with each request

while (fcgi_accept_request(request) >= 0) {
   ...
   php_execute_script(&file_handle);   // zend engine compile and run the opcode
   ...
   php_request_shutdown((void *) 0);  // close connection
}

in function fcgi_accept_request,the socket fd is 4

1411    req->fd = accept(listen_socket, (struct sockaddr *)&sa, &len);
(gdb) n
1414    client_sa = sa;
Breakpoint 6, fcgi_accept_request (req=0x1dae3c0) at /home/dinosaur/Downloads/php-7.2.2/main/fastcgi.c:1414
1414    client_sa = sa;
(gdb) p req->fd
$18 = 4

when close ,it close the socket fd 4

Breakpoint 4, fcgi_close (req=0x1dae3c0, force=0, destroy=1) at /home/dinosaur/Downloads/php-7.2.2/main/fastcgi.c:1272
1272    {
(gdb) p req->fd
$19 = 4

conclusion

so,i think in php7 ,the fpm is close when the request finish,so it is not a persistent connection?

like image 1
Mattia Dinosaur Avatar answered Oct 31 '22 13:10

Mattia Dinosaur