通过fast-cgi连接php-fpm和nginx之间的连接是持久的(保持活动)连接吗?

时间:2017-04-07 14:24:04

标签: php sockets nginx

我正在尝试编写服务器演示来连接php-fpm,但我不知道php-fpm和nginx之间的连接是否是fast-cgi是持久的(保持活动)连接? 每当http请求到nginx时,nginx会再次通过tcp 3-Way Handshake连接php-fpm吗?或者nginx和php-fpm之间的连接是一个keep-alive连接,而nginx尝试重用它?

2 个答案:

答案 0 :(得分:2)

PHP-FPM是fastCGI协议的实现,因此它遵守所有fastCGI规范要求。

section 3.5 of the specification中有一个这样的要求,特别是关于关闭连接:

  

Web服务器控制传输连接的生命周期。没有请求处于活动状态时,Web服务器可以关闭连接。或者Web服务器可以将关闭权限委派给应用程序(请参阅FCGI_BEGIN_REQUEST)。在这种情况下,应用程序在指定请求结束时关闭连接。   这种灵活性适用于各种应用程序样式。简单应用程序将一次处理一个请求,并为每个请求接受新的传输连接。更复杂的应用程序将通过一个或多个传输连接处理并发请求,并使传输连接保持长时间打开。

     

一个简单的应用程序在完成写入响应后关闭传输连接,从而显着提升性能。 Web服务器需要控制长期连接的连接生存期。

     

当应用程序关闭连接或发现连接已关闭时,应用程序将启动新连接。

这意味着由Web服务器决定连接是否会持续存在。这是通过fastcgi_keep_conn选项在nginx中实现的,该选项指出:

  

默认情况下,FastCGI服务器将在发送响应后立即关闭连接。但是,当此伪指令设置为on时,nginx将指示FastCGI服务器保持连接打开。特别是,这对于与FastCGI服务器的keepalive连接起作用是必要的。

此声明旨在反映规范行为以及可以为fastCGI生成的内容提供服务以修改默认行为的Web服务器的功能。

我的假设是,由于网络服务器的线程不断被回收,因此保持连接不存在真正的意义。也许有指定数量的停放线程,但通常的线程池策略是杀死least recently used线程,通常这意味着生成一个新线程将确保预先退出的线程被杀死的线程。

不可否认,我没有找到任何资源来支持nginx的池收集策略是LRU的说法,但它不太可能,并且在这种情况下保持连接存活不会节省太多。

答案 1 :(得分:1)

一年后,我问了这个问题,我似乎找到了答案。

(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

当php-fpm启动时,在初始化之后,它会在while循环中处理每个请求

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
}

在功能fcgi_accept_request中,套接字fd为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

当关闭时,它关闭套接字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

结论

所以,我认为在php7中,请求完成后fpm关闭,因此它不是持久连接?<​​/ p>