在实际的thrift使用过程中,thrift客户端跟服务端通讯会有时爆出org.apache.thrift.transport.TTransportException: java.net.SocketException: Broken pipe异常,复现概率不高,很是困惑不知道是由什么原因引起的,在此记录一下分析和定位的过程,以备查看。
环境:
-centos 7
-jdk1.7
-thrift 0.9.1
-连接管理使用的对象池
问题产生的原因
这个异常产生的原因为thrift客户端向一个已经关闭的socket,写入数据导致该异常发生,在我们的客户端表现为client从对象池获取一个TCP长连接,然后在这个长连接上给服务端发送校验,校验连接是否存活,在实际写入探测字符串的时候,该异常发生,由TIOStreamTransport类在flush的时候抛出,关健的问题点在于客户端向一个已经关闭的socket做写入操作。
这里让我们推测一下,首先该连接已经在服务器端被服务器端显示关闭了,而客户端无法感知该连接已经被关闭,为什么服务器端会将这个连接关闭掉呢?原因有很多,例如:
- 服务器keeplive心跳,检测发现客户端存活,但是网络不可达,服务器就会关闭这个连接
- 连接由于其他原因,例如socket传输异常,导致服务器将这个连接关闭
我们初步怀疑是第一种原因导致的,因为在这个问题发生时,我们的客户端所在的服务还在正常运行。