nginx 500(24:打开文件过多)

nginx 500(24:打开文件过多)

[我在 Nginx 论坛上发布了这个问题,但一周后没有得到任何回复,所以我来这里尝试]

我是 Linux 和 Nginx 新手,但已经学到了足够的知识来安装和运行它,并将其作为两个内部 Web 服务器的简单反向代理。几个月来它一直运行良好,但最近我开始收到 500 错误。

以下是最近的输出/var/log/nginx/error.log (我已将我们的公司名称替换​​为“companyname.com”,并将我们的公共 WAN IP 地址替换为

2020/02/10 15:17:49 [alert] 1069#1069: *1011 socket() failed (24: Too many open files) while connecting to upstream, client: 10.10.10.1, server: web1.companyname.com, request: "GET / HTTP/1.0", upstream: "https://<WANIP>:443/", host: "web1.companyname.com"

2020/02/10 15:21:41 [alert] 1069#1069: *2022 socket() failed (24: Too many open files) while connecting to upstream, client: 10.10.10.1, server: web2.companyname.com, request: "GET / HTTP/1.0", upstream: "https://<WANIP>:443/", host: "web2.companyname.com"

2020/02/10 15:33:28 [alert] 1084#1084: *19987 socket() failed (24: Too many open files) while connecting to upstream, client: 10.10.10.1, server: web2.companyname.com, request: "GET / HTTP/1.0", upstream: "https://<WANIP>:443/", host: "web2.companyname.com"

2020/02/10 15:34:16 [alert] 1084#1084: *39974 socket() failed (24: Too many open files) while connecting to upstream, client: 10.10.10.1, server: web1.companyname.com, request: "GET / HTTP/1.0", upstream: "https://<WANIP>:443/", host: "web1.companyname.com"

2020/02/10 15:50:30 [error] 1086#1086: *1 client intended to send too large body: 4294967295 bytes, client: 176.58.124.134, server: london.companyname.com, request: "GET /msdn.cpp HTTP/1.1", host: "<WANIP>"

2020/02/10 16:32:56 [alert] 1086#1086: *19989 socket() failed (24: Too many open files) while connecting to upstream, client: 10.10.10.1, server: web1.companyname.com, request: "GET / HTTP/1.0", upstream: "https://<WANIP>:443/", host: "web1.companyname.com"

我已将以下内容添加到/etc/security/limits.conf

nginx soft nofile 10000
nginx hard nofile 30000

我已将以下内容添加到/etc/sysctl.conf

fs.file-max=70000

...然后重新启动。但是,重新启动后我立即遇到了同样的问题。

有趣的是,日志中显示的 IP 地址“ 176.58.124.134”我不认识,快速谷歌搜索表明这是一个滥用的 IP 地址。我可以在防火墙处阻止,但我不确定这是否是问题所在。

任何提示、建议都非常感谢。谢谢。

答案1

你的nginx服务器无法跟上到达的请求数量。更确切地说,它缺少可用的文件描述符来打开与上游的连接。

它们由三个参数调节:

  1. 每个系统的限制/proc/sys/fs/文件最大值,限制了最大数量自由度适用于整个系统。不要更改它,默认值已经足够高了(800000在我的小型服务器上)。
  2. 每个进程的硬限制(限制无文件),只能通过(或具有 的进程CAP_SYS_RESOURCES)。这通常相当高(ulimit -Hn,大约1000000),因此无需增加它。如果您想增加它pam_限制配置/etc/security/limits.conf不是帮助你,nginx由 开始systemd(我只能猜测,因为你没有提到你的发行版),它不使用 PAM。你需要编辑该nginx.service文件:

    systemctl edit --full nginx.service
    

    并将以下行添加到该[Service]部分:

    LimitNOFILE=your_limit
    
  3. 每个进程的软限制。nginx可以使用 Romeo 提到的指令自行增加:

    worker_rlimit_nofile = your_limit;
    

每个限制都不能高于前几点的限制。

但是,除非您的网站一夜之间变得非常受欢迎,否则它遭受 DDOS 攻击的可能性更大。您可以通过使用以下方法限制每个客户端的连接数来缓解这种情况http_limit_conn模块。文档中的示例配置应该直接适用于您的案例:

http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    limit_conn addr 10;
    ...

这会将每个 IP 地址的连接数限制为 10。在大多数发行版中,你可以将这两个limit_*指令放在单独的文件中(例如/etc/nginx/conf.d/limit.conf),而无需修改主文件nginx.conf

答案2

当我在代理配置中遇到错误时,我在 Nginx 日志中看到了此消息 - 我错误地将 Nginx 端口号放入 proxy_pass 指令中(而不是上游服务的端口),结果发送到 Nginx 的任何请求都会循环,直到服务器耗尽工作线程,因为打开的连接太多,实际上算作文件。此错误的另一个症状是 Nginx 访问日志不断增长,其中每一行的 IP 地址都比前一行多一次。修复配置文件后,问题就解决了。希望这对某些人有帮助。

相关内容