测试环境没有报错,生产环境每天都有几条这样的报错,网上查了好多资料,翻译成中文大概意思是 Broken pipe(“管道破裂”

错误原因说明:

1)broken pipe的字面意思是“管道破裂”。broken pip的原因是该管道的读端被关闭。

2)broken pipe经常发生socket关闭之后(或者其他的描述符关闭之后)的write操作中。

3)发生broken pipe错误时,进程收到SIGPIPE信号,默认动作是进程终止。

4)broken pipe最直接的意思是:写入端出现的时候,另一端却休息或退出了,因此造成没有及时取走管道中的数据,从而系统异常退出

网上分析原因很多如下
1、报文过大:处理的报文过大,导致客户的端无法解析报文。 

2、文件过大:处理时间过长,由于执行时间较长或频率较高,程序或服务器出发超时直接结束进程。

3、重复提交:处理时间过长导致当客户端重复发送请求,而上次请求尚未完成,下次请求会close上次请求。

4、数据库配置问题:mysql配置文件忘记配置wait_timeout参数,导致数据库连接顺序关闭(RS、PS、CONN)。

5、另外就是:Java虚拟机内存太小或者使用低版本的JVM,出发垃圾回收。

结合项目本身分析:

我的应该是在第二和第三条导致的,client端用户在杀死进程时,接口的TCP请求尚未完成(未完成的原因是处理时间长)。
导致server端write数据时,收到SIGPIPE信号,抛出Broken pipe异常。

说白了就是我请求写入的数据量比较大,处理时间比较长,在测试环境单机测试的情况下,不会有问题。但生产环境数据请求量上来以后,当前一次请求还未处理完,后一个请求就把前一个请求给close掉了,导致write数据时,收到sigpipe(信号污染),抛出出了Broken pipe。

java.net.SocketException: Broken pipe
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
    at org.apache.http.impl.io.SessionOutputBufferImpl.streamWrite(SessionOutputBufferImpl.java:124)
    at org.apache.http.impl.io.SessionOutputBufferImpl.write(SessionOutputBufferImpl.java:160)
    at org.apache.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.java:113)
    at org.apache.http.entity.ByteArrayEntity.writeTo(ByteArrayEntity.java:112)
    at org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:156)
    at org.apache.http.impl.conn.CPoolProxy.sendRequestEntity(CPoolProxy.java:152)
    at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:238)
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
 

解决办法:

我的场景是把身份证照片转成base64数据传输的,压缩前大概两百五十多k。

期初不怎么怀疑因为传输内容过大造成的,但试着对base64数据做了下压缩,在观察线上日志,发现问题确实没有了。

因为上传图片识别,牵扯到客户端和服务端的交互,虽然问题解决了,但我还是怀疑服务端连接设置也存在问题,一次数据传输200多k就造成报错,未免有点儿太过经不起考验,后续有新的发现,还会更新。

参考资料:

https://blog.csdn.net/shenshao_8/article/details/81049456

https://blog.csdn.net/ooppookid/article/details/54891771

https://www.cnblogs.com/cthon/p/9139553.html

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐