Nginx报Connection reset by peer是否因Fire-and-Forget HTTP请求导致?
你的判断完全正确——这个Nginx 104错误确实和你采用的「fire-and-forget」请求模式以及用户操作导致的客户端连接中断直接相关。
错误原因
当你发送POST请求后刻意不等待Axios Promise解析,一旦用户跳转页面、关闭标签页或浏览器,浏览器会主动终止当前未完成的HTTP连接。此时Nginx正处于从上游应用服务器读取响应头的阶段,发现客户端连接被重置,就会记录failed (104: Connection reset by peer) while reading response header from upstream这个错误。本质上这是预期内的客户端主动断开行为,而非服务器或Nginx本身的故障。
解决办法
1. 让Nginx忽略这类错误日志
既然这类错误是业务逻辑允许的,完全可以配置Nginx不再记录它。在你的Elastic Beanstalk对应的Nginx配置文件(比如.ebextensions/nginx/conf.d/custom.conf)中,找到对应API的location块,添加以下配置:
proxy_ignore_client_abort on;
这个参数会让Nginx忽略客户端主动断开连接的情况,不再生成相关错误日志。
2. 替换Axios为更适合的请求方式
对于「fire-and-forget」这类不需要响应的请求,推荐使用浏览器原生的navigator.sendBeacon() API替代Axios。它专门为这类场景设计:
- 浏览器会在后台异步发送请求,不受页面卸载、跳转的影响,能最大程度避免连接被重置
- 不需要处理Promise,天然符合fire-and-forget的需求
示例代码:
const data = new FormData(); data.append('key', 'value'); navigator.sendBeacon('/your-api-endpoint', data);
如果必须使用Axios,可以在发送请求后主动取消请求(效果不如sendBeacon稳定):
const source = axios.CancelToken.source(); axios.post('/your-api-endpoint', data, { cancelToken: source.token }); // 发送后立即取消,避免浏览器等待响应 source.cancel('Fire-and-forget request, no response needed');
3. 服务器端返回即时响应
修改你的API接口,收到请求后立即返回202 Accepted状态码,然后在后台异步处理业务逻辑。这样Nginx能快速拿到响应头并完成请求流程,即使后续客户端断开连接,也不会触发104错误。
比如在Node.js/Express中:
app.post('/your-api-endpoint', (req, res) => { // 立即返回202,告知请求已接收 res.sendStatus(202); // 后台异步处理任务 processTask(req.body); });
内容的提问来源于stack exchange,提问作者user2943799

