我在 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 在加载文件后会释放用于读取文件的内存,对于许多较小的文件,内存使用量远低于加载一个大文件所需的内存。正如我所说,虽然这只是一种直觉,但我可能是错的。