PHP Apache容器不断打开/ proc / * / fd句柄


3

TL:DR: docker中的PHP / Apache不断创建“文件”,/proc/*/fd/最终使站点无法使用。

我们正在docker(php:5.6-apache)中运行一个PHP应用。几周前,我们将该堆栈部署到了生产环境。几天后,客户就无法访问该网站,这是由javascript,图像等各种文件的随机403错误引起的。
据我所知,这是由该错误引起的

[core:crit] [pid 17] (24)Too many open files: AH00529: /var/www/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable and that '/var/www/' is executable

因此,我去检查了Apache进程打开了哪些文件。lsof -a -p 15输出:

apache2  15 www-data   35   unknown                      /proc/15/fd/35 (readlink: Permission denied)
apache2  15 www-data   37   unknown                      /proc/15/fd/37 (readlink: Permission denied)
apache2  15 www-data   38   unknown                      /proc/15/fd/38 (readlink: Permission denied)

访问该网站时,fd编号会连续增加,直到最终达到打开文件的限制。

编辑: 原因(readlink: Permission denied)docker安全功能,因此所有这些句柄实际上都是开放的TCP套接字。

apache2  15 www-data  198u     sock    0,8      0t0 794575 protocol: TCP
apache2  15 www-data  200u     sock    0,8      0t0 795679 protocol: TCP
apache2  15 www-data  201u     sock    0,8      0t0 795681 protocol: TCP

但是netstat没有列出异常打开的连接。netstat -a输出:

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 127.0.0.11:42045        0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
udp        0      0 127.0.0.11:59658        0.0.0.0:*
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node   Path

从来没有见过LAMP堆栈会像这样失败。请检查此Stack Overflow答案以获得一些见解
JakeGould '18

@JakeGould问题是它永远不会关闭文件句柄,因此增加限制只会延迟问题。
Mormund

问题是我从未见过PHP服务器会以这种方式运行。现实情况是,如果您长时间打开流和文件,您似乎会遇到编码/工程问题。PHP并非天生就设计为以这种方式工作。因此,您正在碰壁。我能看到的唯一解决方案是您需要更频繁地关闭文件句柄。但是没有看到您的代码,没有其他建议。发布代码是不切实际的;我在这里看到的是对PHP代码的完整重构或将流程移至其他语言。
JakeGould

Answers:


2

原来我们xdebug安装了扩展程序,但似乎无法正确关闭其套接字。

socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 306
20    fcntl(306, F_SETFL, O_RDONLY|O_NONBLOCK) = 0
20    connect(306, {sa_family=AF_INET, sin_port=htons(9000), sin_addr=inet_addr("0.0.0.0")}, 16) = -1 EINPROGRESS (Operation now in progress)
20    select(307, [306], [306], [306], {tv_sec=0, tv_usec=200000}) = 2 (in [306], out [306], left {tv_sec=0, tv_usec=199998})
20    getpeername(306, 0x7ffe1d6453f0, [16]) = -1 ENOTCONN (Transport endpoint is not connected)20

1
做好侦探工作!在此处查看此答案以获取更多详细信息。XDebug是非生产服务器的有用工具,因此在这种情况下,禁用它是个好主意。但是,仍然很高兴知道彻底禁用它之后可以解决此问题的方法。
JakeGould
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.