如何避免NGINX在后端服务下线时重置已建立的连接?
排查NGINX SMTP代理优雅重启时连接被重置的问题
这个问题我之前帮几个开发者排查过,核心问题通常出在NGINX的SMTP代理配置细节,或者后端优雅重启的实现上,咱们一步步拆解:
1. 先检查NGINX SMTP代理的关键配置
NGINX对SMTP的代理逻辑和HTTP有差异,默认配置可能不满足“保留已建立连接、转发新请求到备用后端”的需求,你需要重点调整这几个指令:
启用TCP连接保活
添加proxy_socket_keepalive on;到你的SMTP server配置块里,这个指令会让NGINX和后端之间的TCP连接保持存活,即使后端关闭了监听套接字,已建立的连接也不会被立即断开,直到当前SMTP会话完成(比如邮件传输结束)。
调整超时参数
SMTP是长连接协议,尤其是传输大邮件时需要更长的时间,默认的超时可能导致NGINX提前断开连接:
proxy_send_timeout 300s; # 给SMTP命令发送留足够时间 proxy_read_timeout 300s; # 等待后端响应的超时时间
正确配置proxy_next_upstream
这个指令决定了NGINX什么时候将请求转发到备用后端,要确保只针对新请求的错误场景触发,不要包含会中断现有连接的条件:
proxy_next_upstream error timeout invalid_header;
避免添加reset或abort这类会强制断开现有连接的触发项。
完整的SMTP代理配置示例:
mail { server { listen 25; protocol smtp; proxy_pass smtp_backend; proxy_socket_keepalive on; proxy_send_timeout 300s; proxy_read_timeout 300s; proxy_next_upstream error timeout invalid_header; upstream smtp_backend { server 127.0.0.1:2525; server 127.0.0.1:2526 backup; # 备用后端 } } }
2. 确认后端的优雅重启逻辑是否正确
如果NGINX配置没问题,那大概率是后端的优雅重启实现有问题:
- 确保后端收到终止信号(比如
SIGTERM)后,只关闭监听套接字,不再接受新连接,但继续处理已建立的SMTP连接,直到所有会话完成再退出。 - 如果后端是直接终止进程(比如
SIGKILL),内核会主动给所有已建立的连接发送RST包,这时候NGINX也会跟着重置连接,这就不是NGINX的问题了。
3. 从日志定位问题根源
查看NGINX的error.log,如果看到类似connection reset by peer的日志,说明是后端主动重置了连接,需要优化后端的优雅重启逻辑;如果是NGINX主动发送RST,那就要再检查proxy_next_upstream和超时配置。
内容的提问来源于stack exchange,提问作者Olerdrive
相关产品推荐
相关产品推荐

