目录
起因
环境:阿里专有云平台
今天发现nginx日志中频繁出现类似Connection reset by peer
的网络连接错误
排查过程
起初怀疑是 Nginx 配置问题,但检查后确认配置正常。随后,通过抓包分析发现这些错误来自 ACK 集群的三个 Master 节点,而这些请求实际上是由 CLB(云负载均衡)实例发起的,CLB 主动向后端服务器发送了 RST(重置)数据包,从而中断了连接
从抓包结果可以看出,CLB 在连接建立后不久,主动发送了 RST 数据包,导致连接被中断。这种情况通常表示 CLB 决定放弃这次连接,或者检测到某种异常而主动关闭了连接。
[S]
表示 TCP 三次握手中的第一次握手(SYN)。[S.]
表示第二次握手(SYN-ACK)。[.]
表示第三次握手(ACK),连接成功建立。[R.]
表示 TCP 连接被重置(RST-ACK)。
问题原因
该问题和CLB的健康检查机制有关。由于TCP协议对上层业务的状态无感知,同时,为了降低健康检查成本以及对后端服务的冲击,CLB针对TCP监听的健康检查只进行简单的TCP三次握手,而后直接发送RST数据包断开TCP连接,没有进一步的业务数据交互,导致上层业务认为连接异常,所以抛出Connection reset by peer
异常。详细的数据交互过程如下:
- CLB实例向后端服务端口发送SYN请求包。
- 后端服务器收到请求后,如果端口状态正常,则按照正常的TCP协议机制返回相应的SYN和ACK应答包。
- CLB实例成功收到后端服务端口的应答,则认为端口监听是正常的,判定健康检查成功。
- CLB实例向后端服务端口直接发送RST数据包主动关闭连接,结束本次健康检查操作,并且不发送业务数据。
解决方案
方案一:更换监听类型(TCP → HTTP/HTTPS)
- 优点:
- 使用 HTTP/HTTPS 监听类型可以更好地处理 HTTP 层的请求,适合 Nginx 作为 Web 服务器的场景。
- CLB 可以更智能地处理连接,减少不必要的 RST 包,同时更好地支持负载均衡和健康检查。
- 缺点:
- 如果你的业务需要保持 TCP 级别的连接(如非 HTTP 协议的服务),更换监听类型可能不适合。
- 可能需要调整 Nginx 配置以适应新的监听类型。
- 适用场景:如果你的业务主要是基于 HTTP/HTTPS 协议的 Web 服务,并且希望减少网络层问题导致的连接重置,这是一个适合的方案。
方案二:日志过滤
- 优点:
- 通过过滤日志中来自 CLB 健康检查的错误信息,可以减少干扰,避免不必要的警报。
- 这种方案不会对现有的业务逻辑和架构造成影响,实施成本低。
- 缺点:
- 仅仅是掩盖了问题,无法真正解决连接重置的根本原因。
- 可能会忽略掉其他潜在的网络问题,导致问题积累。
- 适用场景:如果 CLB 健康检查确实频繁导致连接重置,而这些错误信息对业务无影响,同时希望快速实施解决方案以减轻日志负担,这个方案是一个有效的选择。
方案三:关闭日志级别info
- 优点:
- 关闭
info
日志级别,将仅保留更重要的日志级别,如notice
、warn
和error
,可以减少日志量和不必要的错误信息记录。 - 不影响业务的正常运行和现有架构。
- 关闭
- 缺点:
- 可能会遗漏一些有用的
info
级别日志信息,特别是当问题变得更加复杂时,可能会失去一些诊断数据。 - 依然没有解决问题的根本原因,只是减少了日志输出。
- 可能会遗漏一些有用的
- 适用场景:如果日志中过多的
info
信息干扰了问题的识别,并且这些信息对业务运行没有关键影响,这是一个快速而简单的选择。
推荐方案
结合当前Nginx 服务以及业务的实际需求,如果确认这些错误信息对业务没有实际影响,且主要目的是减少日志中的噪音,那么方案二和方案三都是不错的选择。
- 如果希望彻底清理掉这些不必要的错误信息,方案二可能更合适,因为它能够针对性地过滤掉来自 CLB 健康检查的日志,而不影响其他正常的日志记录。
- 如果希望保持日志的简洁且不需要过多定制,方案三则提供了一个较为简单的方式,通过调整日志级别,减少不必要的日志记录。
建议:可以根据业务需求,选择方案二进行日志过滤,如果未来需要详细的日志分析,再考虑使用方案三来控制日志级别。
标签:reset,方案,TCP,CLB,peer,健康检查,日志,连接 From: https://www.cnblogs.com/Unstoppable9527/p/18355356