解决阿里云CLB的健康检查后业务日志中出现“Connection reset by peer”的错误

起因

环境:阿里专有云平台
今天发现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异常。详细的数据交互过程如下:

  1. CLB实例向后端服务端口发送SYN请求包。
  2. 后端服务器收到请求后,如果端口状态正常,则按照正常的TCP协议机制返回相应的SYN和ACK应答包。
  3. CLB实例成功收到后端服务端口的应答,则认为端口监听是正常的,判定健康检查成功。
  4. CLB实例向后端服务端口直接发送RST数据包主动关闭连接,结束本次健康检查操作,并且不发送业务数据。

解决方案

方案一:更换监听类型(TCP → HTTP/HTTPS)

  • 优点
    • 使用 HTTP/HTTPS 监听类型可以更好地处理 HTTP 层的请求,适合 Nginx 作为 Web 服务器的场景。
    • CLB 可以更智能地处理连接,减少不必要的 RST 包,同时更好地支持负载均衡和健康检查。
  • 缺点
    • 如果你的业务需要保持 TCP 级别的连接(如非 HTTP 协议的服务),更换监听类型可能不适合。
    • 可能需要调整 Nginx 配置以适应新的监听类型。
  • 适用场景:如果你的业务主要是基于 HTTP/HTTPS 协议的 Web 服务,并且希望减少网络层问题导致的连接重置,这是一个适合的方案。

方案二:日志过滤

  • 优点
    • 通过过滤日志中来自 CLB 健康检查的错误信息,可以减少干扰,避免不必要的警报。
    • 这种方案不会对现有的业务逻辑和架构造成影响,实施成本低。
  • 缺点
    • 仅仅是掩盖了问题,无法真正解决连接重置的根本原因。
    • 可能会忽略掉其他潜在的网络问题,导致问题积累。
  • 适用场景:如果 CLB 健康检查确实频繁导致连接重置,而这些错误信息对业务无影响,同时希望快速实施解决方案以减轻日志负担,这个方案是一个有效的选择。

方案三:关闭日志级别info

  • 优点
    • 关闭 info 日志级别,将仅保留更重要的日志级别,如 noticewarnerror,可以减少日志量和不必要的错误信息记录。
    • 不影响业务的正常运行和现有架构。
  • 缺点
    • 可能会遗漏一些有用的 info 级别日志信息,特别是当问题变得更加复杂时,可能会失去一些诊断数据。
    • 依然没有解决问题的根本原因,只是减少了日志输出。
  • 适用场景:如果日志中过多的 info 信息干扰了问题的识别,并且这些信息对业务运行没有关键影响,这是一个快速而简单的选择。

推荐方案

结合当前Nginx 服务以及业务的实际需求,如果确认这些错误信息对业务没有实际影响,且主要目的是减少日志中的噪音,那么方案二方案三都是不错的选择。

  • 如果希望彻底清理掉这些不必要的错误信息,方案二可能更合适,因为它能够针对性地过滤掉来自 CLB 健康检查的日志,而不影响其他正常的日志记录。
  • 如果希望保持日志的简洁且不需要过多定制,方案三则提供了一个较为简单的方式,通过调整日志级别,减少不必要的日志记录。

建议:可以根据业务需求,选择方案二进行日志过滤,如果未来需要详细的日志分析,再考虑使用方案三来控制日志级别。

posted @ 2024-08-12 17:18  &UnstopPable  阅读(55)  评论(0编辑  收藏  举报