在 AWS Beanstalk 部署(单服务器)中,Nginx 服务器与同一主机上的 NodeJS/Express 服务器通信偶尔抱怨与上游的连接丢失。
2020/03/23 10:52:43 [error] 11443#0: *70 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 172.31.46.70, server: , request: "GET /health-check HTTP/1.1", upstream: "http://172.17.0.3:33080/health-check", host: "172.31.39.242"
2020/03/23 10:52:48 [error] 11444#0: *580 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 172.31.21.226, server: , request: "POST /api/app/importNutriwebData HTTP/1.1", upstream: "http://172.17.0.3:33080/api/app/importNutriwebData", host: "******"
2020/03/23 10:52:50 [error] 11443#0: *526 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 172.31.21.226, server: , request: "GET /health-check HTTP/1.1", upstream: "http://172.17.0.3:33080/health-check", host: "172.31.39.242"
这种情况发生没有任何明显的原因,包括/health-check
非常简单的 URL response.send("OK");
。它似乎发生在随机 URL 上。
上游 172.17.0.3 与运行 Nginx 的机器相同。所有下游连接均来自 CloudFront。
同样的设置在过去 3-4 年里运行良好,但这些错误从 2-3 天开始增加。我想不出有什么可能改变,除了或许请求数增加 10% 左右。可能有大约 50 个长期存在的 EventStream 连接,但并发连接数绝不会超过 100 个。我非常确定 NodeJS 服务器没有问题。
我也尝试过升级 Amazon Linux、重启服务器、重建整个 EBS 部署——但什么都没有改变。
curl
我可以对上游 URL( )甚至 CloudFront => Nginx 公共 URL运行无限循环http://172.17.0.3:33080/health-check
,并且尽管在几分钟内尝试了数千个请求(测试),但仍无法重现该问题。
该服务器有大约 1.5 GB 的 RAM自由的,CPU 大约为 80%闲置的。
打开文件句柄对我来说似乎很少:
$ for pid in $(pidof nginx) ; do sudo ls /proc/$pid/fd | wc -w ; done
130
169
11
$ for pid in $(pidof node) ; do sudo ls /proc/$pid/fd | wc -w ; done
146
可能是 Nginx 耗尽了某种资源?是时间问题吗?我该怎么做才能进一步调试?
非常感谢您的帮助。
答案1
看起来您的 NodeJS 应用出于某种原因正在向 nginx 发送 RST 数据包。您可以尝试tcpdump
和/或strace
捕获错误发生时的网络流量和系统调用;然后调查是否有奇怪的事情发生。
该资源可能很有用,它似乎描述了一个非常相似的问题,与保活超时:http://theantway.com/2017/11/analyze-connection-reset-error-in-nginx-upstream-with-keep-alive-enabled