Nginx日志持续出现连接重置/拒绝错误,大并发下异常求助
解决Nginx代理WebSocket(socket.io)时的Connection Reset/Refused问题
嘿,针对你遇到的这两个Nginx错误,结合「用户数超1000才出问题」的情况,我帮你拆解下根源,再给你一步步的排查和修复方案:
首先先弄明白这两个错误到底意味着什么:
recv() failed (104: Connection reset by peer) while proxying upgraded connection:这是Nginx在和你的socket.io后端保持长连接(也就是WebSocket升级后的连接)时,上游服务主动断开了连接。大概率是上游的连接超时、资源耗尽,或者最大连接数被打满了。Connection refused while connecting to upstream:这个更直接——Nginx想和上游服务建立新连接,但被拒绝了,几乎可以肯定是上游服务已经接不住更多并发了,要么是连接数到顶,要么是服务临时过载卡壳了。
接下来是具体的解决步骤,按优先级来:
1. 先把Nginx的WebSocket代理配置拉满
因为你用的是socket.io的升级连接,基础配置必须到位,而且要针对高并发调整:
- 确保你已经开启了HTTP/1.1和WebSocket升级头,这是WebSocket正常工作的前提;
- 把超时时间调大,避免Nginx或上游过早断开长连接;
- 提升Nginx的全局连接处理能力,比如worker进程数和单进程连接数。
给你一个参考配置:
# nginx.conf 全局events块 events { worker_processes auto; # 和CPU核心数匹配,充分利用硬件 worker_connections 10000; # 单进程能处理的最大连接数,调大到能支撑1000+用户 multi_accept on; # 让worker进程一次性接受所有新连接 } # 站点配置里的socket.io location块 location /socket.io/ { proxy_pass http://你的上游服务地址; # 比如http://127.0.0.1:3000 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # 调长超时时间,适配WebSocket长连接 proxy_connect_timeout 600s; proxy_send_timeout 600s; proxy_read_timeout 600s; }
2. 排查上游服务的连接数瓶颈
如果是Node.js这类后端,默认的文件句柄限制很低(通常是1024),而每个WebSocket连接都会占用一个文件句柄,用户数超1000时肯定会不够用:
- 先执行
ulimit -n查看当前的文件句柄限制,如果是1024,赶紧改大:- 临时生效:
ulimit -n 65535 - 永久生效:编辑
/etc/security/limits.conf,添加下面两行,然后重启系统:* soft nofile 65535 * hard nofile 65535
- 临时生效:
- 同时检查socket.io的心跳配置,避免上游因为心跳超时主动断开连接:
const io = require('socket.io')(server, { pingTimeout: 60000, // 60秒没收到心跳才断开 pingInterval: 25000, // 每25秒发一次心跳包 });
3. 给上游服务做负载均衡
如果单台上游服务撑不住1000+并发,直接搭集群,用Nginx做负载均衡分散压力:
# 定义上游集群 upstream socket_servers { server 127.0.0.1:3000; server 127.0.0.1:3001; server 127.0.0.1:3002; ip_hash; // 用IP哈希,保证同一个用户的连接始终打到同一台上游,避免socket.io会话丢失 } # 然后把proxy_pass指向这个集群 location /socket.io/ { proxy_pass http://socket_servers; # 其他WebSocket配置和之前一样 }
4. 调整系统TCP参数,释放连接瓶颈
系统层面的TCP连接限制也可能拖后腿,比如TIME_WAIT连接堆积,导致新连接建不起来:
- 编辑
/etc/sysctl.conf,添加这些参数:net.ipv4.tcp_tw_reuse = 1 # 允许复用TIME_WAIT的连接 net.ipv4.tcp_tw_recycle = 1 # 快速回收TIME_WAIT连接 net.ipv4.tcp_max_syn_backlog = 8192 # 增大SYN队列长度,避免高并发时丢包 net.core.somaxconn = 65535 # 增大系统最大监听队列长度 - 执行
sysctl -p让参数生效。
最后,建议你在高并发时监控上游服务的CPU、内存、文件句柄使用情况,用top、lsof -p <上游进程ID> | wc -l这些命令,定位具体是哪个资源先耗尽,然后针对性优化。
内容的提问来源于stack exchange,提问作者Bharat singh
相关产品推荐
相关产品推荐

