SO_LINGER选项用来控制Socket关闭时的行为,默认情况下,执行Socket的close方法,该方法会立即返回,但底层的Socket实际上并不会立即关闭,他会立即延迟一段时间,直到发送完剩余的数据,才会真正的关闭Socket,断开连接。
setSoLinger(true, 0): 执行该方法,那么执行Socket的close方法,该方法也会立即返回,但底层的Socket也会立即关闭,所有未发送完的剩余数据被丢弃.
setSoLinger(true, 6): 那么执行Socket的close方法,该方法不会立即返回,而进入阻塞状态,同时,底层的Socket也会尝试发送剩余的数据,只有满足下面的两个条件之一,close方法才会返回:
(1):底层的Socket已经发送完所有的剩余数据
(2):尽管底层的Socket还没有发送完所有的剩余数据,但已经阻塞了6秒,close()方法的阻塞时间超过6秒,也会返回,剩余未发送的数据被丢弃。
示例一:
问题描述
某省账号在微信公众号支付时提示第三方平台支付失败,失败率较高。Connection reset
异常日志
121509:41:33.380 [pool-2-thread-373] INFO NoticeUtil – [P531215000893588] 功能码[plat_reqPay]不需要通知清分系统
121509:41:33.399 [pool-2-thread-342] ERROR HttpUtils – IO异常
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:168) ~[na:1.6.0_45]
at org.apache.http.impl.conn.LoggingInputStream.read(LoggingInputStream.java:87) ~[httpclient-4.3.3.jar:4.3.3]
at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:136) ~[httpcore-4.3.2.jar:4.3.2]
at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:152) ~[httpcore-4.3.2.jar:4.3.
问题原因
服务器端关闭连接时,客户端未读完数据。
省平台在发送响应之后立即关闭连接。惠商+读省平台响应时,Connection reset异常。服务器端关闭连接,客户端仍然在读数据,服务器会返回复位标志“RST”,客户端就会提示“java.net.SocketException: Connection reset”
解决方法
省平台修改bs2_cmccpay.xml配置Service4_http 的 soLinger为1,最多阻塞一秒在关闭链路
示例二:
问题描述
1.并发用户数为100,压力1分钟40秒左右,业务后台和客户端的所有连接突然断开(除了自身的端口8115),客户端前置报错
异常日志
09-26 11:48:40.738 [pool-3-thread-42] INFO – * (0x0002FFF2: NioSocketAcceptor, null => /10.10.73.89:8114)…Sessions=4
09-26 11:48:40.738 [pool-3-thread-42] INFO – * [0x0002FFF2] 读1/736B,写1/464B,历时90ms,读写速度:22.2(R+W/s)/13.33(KB/s)…Mina2HandlerAbstract.onClosed()
09-26 11:48:56.260 [MTTask#18748] WARN – E m_connect(/10.10.73.90:8115).getSession()=null
09-26 11:48:56.260 [MTTask#18748] WARN – E m_open(null).m_connect() = null
问题原因
front3_common.xml中的对平台客户端中的soLinger配置1(1是指在调用close方法后,将最多被阻塞1秒。在这1秒内,系统将尽量将未送出的数据包发送出去;如果超过了1秒,如果还有未发送的数据包,这些数据包将全部被丢弃 ;0是指不论是否有未发送的包均立即关闭连接)
解决方法
将front3_common.xml中的对平台客户端中的soLinger配置从1改成0