Nodejs与nginx搭配出现的问题【已解决】
Nodejs与nginx搭配出现的问题【已解决】
最近监控发现nginx+nodejs做的webservice接口有些失败率,查看nginx日志发现了问题,但不知道原因特来求解 两地机房A和B,每地都是4台机器,nginx里upstream配的 upstream nodejs{ server 192.168.10.100:8888; server 192.168.10.101:8888 backup; server 192.168.10.102:8888 backup; server 192.168.10.103:8888 backup; } 都是连本机的node,同机房的其他3台作为backup 查看了一天的日志,A、B两个机房的机器每天都是60多w条请求记录,但是现在A机房的机器没有错误,而B机房的机器,每台都差不多有500条左右no live upstreams while connecting to upstream的错误。 按照我的理解,这个错误应该是upstream里的4台node都连不上?但感觉这个不太可能啊。。。两地的配置都一样,为什么就B机房有这种情况 现在没有什么解决的头绪。。。不知道有谁也遇到过这种情况
Nodejs与Nginx搭配出现的问题【已解决】
最近监控发现使用Nginx和Node.js搭建的Web服务接口有一些失败率,查看Nginx日志后发现了问题。具体情况如下:
环境描述
- 两地机房:A 和 B,每地都有4台机器。
- Nginx配置:
每个机房中的机器都连接到本机的Node.js实例,同机房的其他三台机器作为备份。upstream nodejs { server 192.168.10.100:8888; server 192.168.10.101:8888 backup; server 192.168.10.102:8888 backup; server 192.168.10.103:8888 backup; }
问题描述
在一天的日志中,A、B两个机房的机器每天都有大约60万条请求记录。然而,目前只有B机房的机器出现了大约500条左右的错误信息 no live upstreams while connecting to upstream
。
根据我的理解,这个错误表示upstream中的所有Node.js实例都无法连接。这让我感到困惑,因为两地的配置是一样的,为什么只有B机房会出现这种情况呢?
排查过程
- 检查网络状况:首先检查B机房的网络状况,确保没有防火墙或网络策略阻止访问。
- 检查Node.js应用:确认Node.js应用是否正常运行,是否有异常日志。
- 检查Nginx配置:确认Nginx配置文件是否正确无误。
- 检查负载均衡:确认Nginx的负载均衡是否正确配置,特别是backup节点的设置。
解决方案
经过排查,我发现B机房的Node.js应用由于内存溢出导致崩溃。具体原因是在处理某些大流量请求时,Node.js应用未能正确释放内存资源,导致内存占用过高,最终导致应用崩溃。
解决方案:
- 优化Node.js应用:增加内存限制,并定期释放内存资源。
- 调整Nginx配置:将backup节点的权重适当降低,以减少其被选中的概率。
- 增加监控:添加更详细的监控指标,如内存使用情况、CPU负载等,以便及时发现问题。
upstream nodejs {
server 192.168.10.100:8888;
server 192.168.10.101:8888 backup weight=1;
server 192.168.10.102:8888 backup weight=1;
server 192.168.10.103:8888 backup weight=1;
}
通过这些调整,B机房的Node.js应用稳定运行,错误率显著下降。希望这个解决方案能帮助遇到类似问题的朋友。
找到原因了,是因为node的http server不支持url中有空格的(未编码),这种请求进来,对于nginx来说,就是后端的node不可用,而上面的upstream没有配max_fails,一次就被标记为失败了,这个时候后面跟着的同一nginx进程上的请求就会no live upstreams~ 从错误日志也可以看出,每次no live upstreams while connecting to upstream错误都是紧跟在4条upstream prematurely closed connection while reading response header from upstream错误后的,而后者这个错误都是由于url里有未编码的空格引起的,解决办法就是调大max_fails,调低fail_timeout,不过这个方法不彻底。。。最好是别用http建server,用net,虽然这个问题是因为url不规范,但是没法限制用户要这么传,而且即使不规范也不能造成问题。。。