Broken Pipe发生的原因

当某个进程试图往一个已收到RST的SOCKET连接写数据,就会出现Broken Pipe。
(由于TCP协议层已经处于RST状态了,因此不会将数据发出,而是发一个SIGPIPE信号给应用层,SIGPIPE信号的缺省处理动作是终止程序。)

那么确定什么时候TCP会发送RST报文段,就可以确定Broken Pipe发生的具体原因。

之前已经分析了TCP RST报文产生的几种情景了。

原因分析

broken pipe出现的前提条件是进程试图往一个已经在RST状态的TCP连接写入数据。

那么这个写入数据,到底应该怎么理解呢?到底是进程试图往本地SendQ发送缓存区写入数据还是TCP协议试图将SendQ的数据发送到对端的RecvQ呢?按照字面意思应该是前者。

之前我们已经分析了几种会出现RST报文的情况。
结合我们出现该异常的接口分析。我们发现我们出错的接口,返回的数据,最小的8K多,最大的超过128K。查阅了几天的异常日志,都没有发现一个报出broken pipe异常错误的接口的返回数据小于8K。

根据RST报文产生的情况,我们可以做出如下推断,当Client端与我们的服务器建立了TCP链接之后。当TCP协议将服务端SendQ队列里的内容发送到对端(Client)的ReceQ队列中后,Client关闭了进程,此时ReceQ 读取缓存区还有数据未被读取(不管ReceQ的数据Client端有没有读取过,也不管TCP将多少服务端的数据发到了ReceQ,总之,就是在关闭的时候,还有数据存在于读取缓存区中),这时候关闭socket,会导致端Client端产生一个RST重置报文。
这时候服务端的数据还没有写完,会继续写入,当再次写入的时候,TCP协议已经是RST状态的了,这个时候,就会发生broken pipe。

上面的推论能够解释broken pipe发生的一整个流程。

那我们来查看下linux服务器的默认SendQ大小与我们接口返回的数据大小的对比,就能够是否确实是这些接口的数据写入都需要多次写入缓存区。

那么如何查看linux默认的SendQ缓冲区大小呢。linux给我们提供了相应的命令

ubuntu@VM-104-50-ubuntu:/data/iyourcar$ cat /proc/sys/net/ipv4/tcp_wmem
4096    16384   4194304最小    默认     最大

我们发现,默认写缓存区大小是16k,可是我们的接口返回的数据最小的是8k多呀,这个接口返回的数据是可以一次写入缓存区的呀。咋回事呀,怎么这样也会broken呢。如果服务端一次性写入16k数据到写缓存区,那么是不可能出现broken pipe的呀。那只能证明我们的程序并不是一次性写入16k的数据给缓存区,这个大小肯定是要比8k多要小的。那我们就来求证一下,用一个会报出异常的接口在出现异常的地方进行debug,主要debug写入数据的流程。

使用的内置容器是Tomcat

OutputBuffer#appendByteArray

public static final int DEFAULT_BUFFER_SIZE = 8 * 1024;public OutputBuffer() {this(DEFAULT_BUFFER_SIZE);}private void appendByteArray(byte src[], int off, int len) throws IOException {if (len == 0) {return;}int limit = bb.capacity();//我们发现,每一次写入的字节数bb.capacity()大小,而默认的capacity大小就是8*1024,也就是8kwhile (len >= limit) {realWriteBytes(ByteBuffer.wrap(src, off, limit));len = len - limit;off = off + limit;}if (len > 0) {transfer(src, off, len, bb);}}

我们发现,实际上,tomcat帮我们向socket写入数据的时候,是每8k写入一次SendQ(但是真正TCP发送数据,可能是分很多块去发送到对端的ReceQ的)

后来我们将内置web容器换成了undertow,发现依旧会发生这种情况,应该默认也是一次写入8k吧,具体还没有debug。

所以当使用的容器是tomcat的时候,只要接口返回数据的大小大于8k,就可能会出现broken pipe。

Broken Pipe相关推荐

  1. TNS-12518 Linux Error:32:Broken pipe

    最近一周,有一台ORACLE数据库服务器的监听服务在凌晨2点过几分的时间点突然崩溃,以前从没有出现过此类情况,但是最近一周出现了两次这种情况,检查时发现了如下一些信息: $ lsnrctl servi ...

  2. JedisConnectionException: java.net.SocketException: Broken pipe

    问题:redis一台,内存15g,32个现成共同操作redis!数据量160w,报出:JedisConnectionException: java.net.SocketException: Broke ...

  3. linux ssh 报错 Write failed: Broken pipe 解决方法

    目录 原理 方法1:通过客户端配置 方法2:服务器端配置 方法3:临时SSH命令配置 总结 在使用SSH连接远程服务器的时候,如果长时间不操作,再次进入 Terminal 时就会有卡死一段时间没有响应 ...

  4. 服务器可以ping通,Write failed: Broken pipe

    服务器可以ping通,ping无丢包,延迟很低,但是ssh连接的时候需要等一会然后显示admin@admin:~$ ssh 10.10.25.21 admin@10.10.25.21's passwo ...

  5. vm显示打不开 /dev/vmmon:Broken pipe

    这个主要是vm打开时系统拒绝他说没有vmmon这个文件  因为是broken pipe.所以应该是通道性的问题 也就是vm给本机发送文件,本机未收到相应的信息.或是相反.所以先考虑到系统阻止访问到问题 ...

  6. java.io.IOException: Broken pipe 的异常处理

    断开的管道 java.io.IOException: Broken pipe 解决方法 一.Broken pipe产生原因分析 1.当访问某个服务突然服务器挂了,就会产生Broken pipe; 2. ...

  7. 调用 usb_control_msg 返回错误值 -32, Broken pipe, 对 hidraw write时 返回错误值 -32, Broken pipe

    -------------------Step 1--------------------- 如题,使用 libusb 对 hid 类设备进行控制传输的时候,有时会遇到此错误,但是实际上传输是成功的, ...

  8. 断开的管道 java.io.IOException: Broken pipe 解决方法

    断开的管道 java.io.IOException: Broken pipe 解决方法 一.Broken pipe产生原因分析 1.当访问某个服务突然服务器挂了,就会产生Broken pipe; 2. ...

  9. gdb调试时,Program received signal SIGPIPE, Broken pipe.

    今天在gdb调试时,发现总是出现Program received signal SIGPIPE, Broken pipe,搜索了网上的资料,发现是在调试时,接收到了SIGPIPE这个signal信号导 ...

  10. java.net.SocketException: Broken pipe问题解决

    2019独角兽企业重金招聘Python工程师标准>>> javax.servlet.ServletException: ClientAbortException:  java.net ...

最新文章

  1. win10 创建python虚拟环境
  2. 《IBM-PC汇编语言程序设计》(第2版)【沈美明 温冬婵】——第七章——自编解析与答案
  3. android 一个有漂亮动画效果的Dialog
  4. linux中yum与rpm区别
  5. DevOps的前世今生
  6. 阿里P8大佬亲自讲解!朝阳java培训
  7. .net 反编译_向.net/Unity 程序员推荐一个十分因吹斯听的网站:sharplab.io
  8. 不是我的错,也不是Atlas的!
  9. 动态链接库的隐式动态链接和显示动态链接
  10. Anders Hejlsberg谈C#、Java和C++中的泛型
  11. 自治系统中单个路由表的构造
  12. 上海工程技术大学c语言商店存货管理系统,商店存货管理系统课程设计.doc
  13. mysql如果索引为uid间隙锁_MySQL-浅析间隙锁
  14. 点云最小二乘法拟合空间直线
  15. 三种古典密码的认识(置换密码,代换密码和轮换密码)
  16. python处理grd格式文件_python基础
  17. Thinkpad笔记本键盘拆卸
  18. MoCo 动量对比学习——一种维护超大负样本训练的框架
  19. 如何通过 WhatsApp 开展营销活动?
  20. Android蓝牙开发系列文章-蓝牙mesh(一)

热门文章

  1. SAP 之定义工厂(Plant)
  2. rpm安装java_【CentOS】rpm包安装Jdk
  3. 【计算机图形学 】绘制椭圆 | OpenGL+鼠标交互
  4. Python 字符串重复判断
  5. 43岁,转行当了大学老师
  6. 网络诈骗有哪些防范措施
  7. 【Scratch考级99图】图36-等级考试scratch绘制复杂图形中间带凸点正方形花 少儿编程 scratch画图案例教程
  8. 数据耦合的代码例子c语言,代码耦合的处理
  9. 计算机表格中的乘法怎么用,excel表格中怎么使用乘法公式
  10. 云空间插虾米html音乐,总结一下可以上传MP3并外链的空间