背景
部署TCP服务,对外暴露端口号,提供给设备连接,实现设备和服务双向通信。
网关架构
问题描述
设备连接上服务端连接后不久自动断开,服务端的业务日志中频繁出现 readAddress(…) failed: (onnection reset by peer。
排查思路
环境变量:
- 生产环境的服务和测试环境一样的
- 设备的SDK没有改变
- TCP链路生产环境和测试环境配置是不同的
问题方向:
生产TCP链路配置不太一样,排查方向选择生产环境的网络链路问题
验证问题猜想:
协同运维同事快速配置公网IP+NGINX链路映射到TCP服务。设备连接服务域名修改成临时的公网IP,重新连接TCP服务。设备可以正常和服务通信,并且不会自动断开。
初步判断:
生产环境应为配置CLB造成设备无法正常连接服务端
问题原因:
阿里云: 开启传统型负载均衡CLB的健康检查后业务日志中出现“Connection reset by peer”的错误
该问题和CLB的健康检查机制有关。由于TCP协议对上层业务的状态无感知,同时,为了降低健康检查成本以及对后端服务的冲击,CLB针对TCP监听的健康检查只进行简单的TCP三次握手,而后直接发送RST数据包断开TCP连接,没有进一步的业务数据交互,导致上层业务认为连接异常,如Java连接池等,所以抛出Connection reset by peer异常。详细的数据交互过程如下:
- CLB实例向后端服务端口发送SYN请求包。
- 后端服务器收到请求后,如果端口状态正常,则按照正常的TCP协议机制返回相应的SYN和ACK应答包。
- CLB实例成功收到后端服务端口的应答,则认为端口监听是正常的,判定健康检查成功。
- CLB实例向后端服务端口直接发送RST数据包主动关闭连接,结束本次健康检查操作,并且不发送业务数据。
验证问题:
关停CLB针对TCP监听的健康检查,设备恢复通过域名连接服务端。设备可以正常和服务通信,并且不会自动断开。
解决方案
恢复CLB链路,更换监听类型更换CLB的TCP监听为HTTP监听或HTTPS监听,详情请参见添加HTTP监听和添加HTTPS监听。