
# ELB四层健康检查导致java报错：Connection reset by peer
#### 完整错误信息
```
java.io.IOException: Connection reset by peer
at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
at sun.nio.ch.IOUtil.read(IOUtil.java:197)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
at com.wanyu.smarthome.gateway.EquipmentSocketServer.handleReadEx(EquipmentSocketServer.java:245)
at com.wanyu.smarthome.gateway.EquipmentSocketServer.run(EquipmentSocketServer.java:115)
```
#### 分析结果
使用Java NIO建立Socket服务端，当客户端意外关闭的情况，不是发送指定指令通知服务器退出，就会产生此错误。
#### TCP健康检查的机制
1. ELB节点根据健康检查配置，向后端服务器（IP+健康检查端口）发送TCP SYN报文。
2. 后端服务器收到请求报文后，如果相应的端口已经被正常监听，则会返回SYN+ACK报文。
3. 如果在超时时间内没有收到后端服务器的SYN+ACK报文，则判定健康检查失败，然后发送RST报文给后端服务器中断TCP连接。
4. 如果在超时时间内收到了SYN+ACK报文，则发送ACK给后端服务器，判定健康检查成功，并发送RST报文给后端服务器中断TCP连接。
 
#### 注意
正常的TCP三次握手后，会进行数据传输，但是在健康检查时会发送RST中断建立的TCP连接。该实现方式可能会导致后端服务器中的应用认为TCP连接异常退出，并打印错误信息，如"Connection reset by peer"。
**这种错误是合理范围内的，无法避免的，不必关心它。**
