PHP-FPM 是一个优秀的 PHP 进程管理器。在高负载站点上,我们使用 lighttpd 以及 PHP-FPM 处理 Web 请求。
然而最近我们发现 lighttpd 几乎每天都会报错,此时 PHP 请求全部不处理,而 PHP 进程却健在。百思不得其解,看到 lighttpd 的日志大概如下
2011-10-30 09:20:01: (mod_fastcgi.c.2566) unexpected end-of-file (perhaps the fastcgi process died): pid: 0 socket: tcp:127.0.0.1:9000
2011-10-30 09:20:01: (mod_fastcgi.c.3354) response not received, request sent: 1795 on socket: tcp:127.0.0.1:9000 for /index.php?, closing connection
而 PHP-FPM 的日志里却一点也没有痕迹。重启 PHP-FPM 一切正常。
UNIX 系统 listen() 函数将 sockfd 对应的 socket 标记为被动 socket。TCP连接模型中,服务器是被动连接的。 listen() 函数有请求数量限制,即为 backlog. 下面是 listen() 函数的用法:
int listen(int socket, int backlog);
这里的 backlog, 原文解释如下:
The backlog parameter defines the maximum length for the queue of pending connections. If a connection request arrives with the queue full, the client may receive an error with an indication of ECONNREFUSED. Alternatively, if the underlying protocol supports retransmission, the request may be ignored so that retries may succeed.
问题真相大白。修改 php-fpm 的配置文件,设定 backlog 为 -1 即可。注意查看 max-file (/proc/sys/fs/file-max)的值。这里有一篇详细的关于文件描述符的文章。