【经验教训】Broken pipe等

最近产品线中又碰到Broken pipe的问题,之前也碰到过,但分析了下,原因是不同的。

情景一:

在一个网络传输的模块中,由于Broken pipe导致服务程序退出。

分析:经常写网络服务的的人也许知道,一般在启动等过程中由于系统不稳定一般会先忽略一些信号量,或者说捕捉一些信号量并作特殊处理。以防其直接导致程序退出。就比如SIGPIPE。

在socket交互过程中,建立连接后,如果client端意外中断,而此时恰好server端处于socket write过程时,会向主程序发送SIGPIPE信号,此时如果主程序不做特殊处理,系统默认的处理方式为退出进程。对于产生信号,我们可以在产生信号前利用方法 signal(int signum, sighandler_t handler) 设置信号的处理。

情景二:

这是今天刚遇到的,追查起来还挺麻烦的,因为报出Broken pipe错误的程序没有进行网络通信。大致形式类似与:

+ cat temp.data
+ ./XXX.exe
map.sh: line 108: 12915 Broken pipe             cat temp.data
     12916 Killed                  | ./XXX.exe >data.output

这是一个map reduce任务的map中的一段,其中XXX.exe是C++写的一个数据处理程序,没有网络交互。

面对问题的出现,当时的第一反应是怀疑那个节点的磁盘满了导致数据流堵住。

再次进行重试进行复现,结果发现还是出现Broken pipe ,并且是很多节点都这样。由此判断不是磁盘问题。然后查看XXX.exe的相关日志,发现他的日志是不完整的,在加载字典的过程中,只执行了一半便没有任何征兆地中断了。当时就突然想到一个问题,可能是内存不足。于是,调整map reducer的内存限制,再次重试,这次成功执行了。

由此,推断此次Broken pipe 的产生过程是这样的:

XXX.exe的内存寻求比如是2G,而我们设置了map reducer的内存上限为1G,结果在执行XXX.exe时,内存超限被直接干掉了。这时候相当于cat temp.data |./XXX.data 这一过程的cat管道下游的接受方死掉了,于是乎报出管道破裂的报警。

像这种,出现问题的表象与实质原因之间还是有一定距离的,似乎是八竿子打不到一起的。这种case在工作中处理还是挺恶心的。

你可能感兴趣的:(Broken,pipe)