nginx 中出现大量重定向,无法分配内存错误

nginx 中出现大量重定向,无法分配内存错误

我在 nginx 中遇到了内存分配错误。我在 nginx 上为许多站点配置了反向代理,将其用作两个后端节点之间的简单负载平衡器。站点的典型配置如下所示:

upstream backend  {
  ip_hash;
  server <node-ip>;
  server <another-node-ip>;
}

server {
  server_name domain.subdomain.com;    

  # a HUGE bunch of redirection rules 
  include /etc/nginx/sites-available/root;

  location / {

    proxy_pass  http://backend  ;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

我有 12 个站点,配置如上。如您所见,配置包含include另一个文件 - sites-available/root。此文件包含unclude指向其他文件的若干指令:

include /etc/nginx/sites-available/rules1;
include /etc/nginx/sites-available/rules2;
include /etc/nginx/sites-available/rules3;
...
include /etc/nginx/sites-available/rules16;

每个规则文件都包含许多重定向规则,例如:

if ($request_uri ~* ^/some-url$) {
  return 302 /some-another-url/;
}

或者

location ~ some-url {
  return 302 "some-another-url";
}

重定向规则总数约为 2300 条。我将root文件添加到所有 12 个站点的配置中。此后,我一次又一次地收到以下信息消息/var/log/nginx/error.log

[info] 23721#23721: 在 /etc/nginx/nginx.conf:66 中为推送模块使用 32768KiB 共享内存

主要问题是有时命令service nginx reload会失败并在日志中显示错误:

[警报] 22164#22164:fork() 在生成“工作进程”时失败(12:无法分配内存) 2018/10/09 03:10:06

[警报] 22164#22164:sendmsg() 失败(9:错误的文件描述符)

如果我从配置中排除重定向规则,问题就消失了。Nginx 安装在使用 Ubuntu 16.04 的简单 AWS t2.small 实例上。它有 1GB 的 RAM,我看到(使用free -m)至少有一半的内存是空闲的。我有默认的 nginx.conf。那么问题是如何避免cannot allocate memory由大量重定向规则引起的错误?

这个问题最初发布于这里。我以为这里有人知道答案。抱歉重复了。

答案1

如果文件很大,请将其拆分成较小的部分。我有一个 1.8MB 的文件,其中大约有 20k 个重定向,内存不足的实例无法处理,并给出了你所得到的错误。我通过以下方法修复了它:

mkdir /etc/nginx/conf.d/redirects
split -l 1000 redirect_file redirect_folder/

...然后只需将文件夹包含在服务器配置中,例如:

server {
    listen 127.0.0.1:80
    ...
    include conf.d/redirects/*;
    ...
}

然后 Nginx 就可以正常加载了。我猜是这样的,但我的直觉是 nginx 在加载文件后会释放用于读取文件的内存,对于许多较小的文件,内存使用量远低于加载一个大文件所需的内存。正如我所说,虽然这只是一种直觉,但我可能是错的。

相关内容