linux – 从网络连接读取时无限期挂起的进程

前端之家收集整理的这篇文章主要介绍了linux – 从网络连接读取时无限期挂起的进程前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
以下更新:

我在一个不相关的脚本上遇到了类似的问题,在不同数据中心的Debian虚拟机上.

这看起来像是here所描述的问题(就像问这个问题的人一样,我没有在服务器前面配置代理).

与下面描述的主要区别在于,当我附加到挂起的进程时,我看到对recvfrom的调用而不是读取:

$strace -p 17527
Process 17527 attached - interrupt to quit
recvfrom(3,

然而,Python并没有任何印象它被代理:

>>> import os; print os.getenv("HTTP_PROXY"),os.getenv("http_proxy")
None,None

所以我仍然难过.可悲的是,相关问题也没有最终答案.

(我也想知道this question是否相关,但S3似乎不太可能无法接受Connection:关闭标题.)

我有几个Debian(Wheezy,x86_64)服务器都表现出以下行为:

所有服务器都有一组cron作业,其中包括从S3中提取数据.这些通常运行良好,但偶尔ps aux显示几小时或几天前开始的一些工作仍在运行,并且还没有完成干净.

用strace -p< pid>检查它们显示,在所有情况下,进程都挂在读取命令上.例如,我刚刚检查过的输出是:

$strace -p 12089
Process 12089 attached - interrupt to quit
read(5,

检查打开的文件描述符给了我这个:

$sudo lsof -i | grep 12089
python  12089    user    5u  IPv4 809917771      0t0  TCP my.server.net:35427->185-201.amazon.com:https (ESTABLISHED)

起初我认为这只是由于在Python脚本中没有设置读取超时,但由于以下几个原因,情况似乎并非如此:

>当使用相同的代码在我们的OS X盒(全部10.5,i386)上运行相同的作业时,不会发生这种情况.
>脚本的一个变体确实设置了一个超时(60秒,使用socket.setdefaulttimeout – 这是在Python 2.7中,但代码库必须是2.5兼容的)从昨天起已经挂起.
>另一个不是Python的进程似乎偶尔会表现出类似的行为.在这种情况下,Python脚本正在执行一个svn up – 非交互式进程(使用subprocess.Popen,这是值得的).

SVN流程的情况类似 –

Python正在等待SVN:

$strace -p 28034
Process 28034 attached - interrupt to quit   
wait4(28127,

SVN正在等待读取调用完成:

$strace -p 28127
Process 28127 attached - interrupt to quit
read(6,

那个读取指向另一个外部主机:

$sudo lsof -i | grep 28127
svn     28127    user    3u  IPv4 701186417      0t0  TCP my.server.net:49299->sparrow.telecommunity.com:svn (ESTABLISHED)
svn     28127    user    6u  IPv4 701186439      0t0  TCP my.server.net:49309->sparrow.telecommunity.com:svn (ESTABLISHED)

(在更新的目录上似乎有一个svn:externals属性设置为ez_setup svn://svn.eby-sarna.com/svnroot/ez_setup;基于他们的网站,我认为这是重定向到telecommunicationity.com)

其他可能相关的要点:

> Mac上的Python环境是2.5.在Debian框中,它是2.7.
>我不是很精通SVN,我不知道它悬挂的原因是否基本相同.我也不完全确定svn:externals的含义是什么;这是在我的时间之前建立的.
> Python脚本本身正在从Amazon S3中检索大量数据(在某些情况下约为10MB)数据块,而且这种数据趋于缓慢(我看到下载时间长达三分钟,这似乎与服务器 – 即使在不同的数据中心 – 彼此通信需要多长时间.同样,我们的一些SVN存储库相当大.因此,基本上可以说这些操作中的一些无论如何都是长期运行的,但是在某些情况下它们似乎也会挂起几个小时或几天.
>在一台服务器上,OOM杀手今天早上取出了MysqL.经过仔细检查,内存使用率为90%,交换使用率为100%(Monit报告);杀死大量积压的挂起的Python工作,这些数据分别降低了60%和40%.这给我的印象是,至少有一些(如果不是全部)数据被下载/读取(并且在进程挂起时保存在内存中).
>这些cron作业正在从S3请求资源列表,并相应地更新MysqL表的列表.每个作业都以相同的列表启动,因此将尝试请求相同的资源并更新相同的表.
>我能够从一个挂起的进程中捕获一些流量;这对我来说有点难以理解,但我想知道它是否表明连接是活动的并且正常工作,只是非常慢?我已经提供了它作为一个要点,以避免混乱(我应该注意这是大约两个小时的捕获):https://gist.github.com/petronius/286484766ad8de4fe20b我认为这是一个红鲱鱼.该端口上有活动,但它与S3的连接不同 – 它只是其他随机服务器活动.
>我试图在另一个数据中心(运行相同版本的Debian并使用相同系统设置的VM)的盒子上重新创建此问题,但没有运气(我想也许这个问题可能与this one有关,但遇到这些问题的方框不是虚拟机,根据ifconfig没有丢弃的数据包).我想这表明网络配置问题,但我不知道从哪里开始.

所以我想我的问题是:

>我可以在系统级别修复此问题,还是每个进程出错?
>对于OS X和Linux如何处理我需要知道的读取调用以避免无限挂起的进程,是否存在根本不同的东西?

解决方法

Can I fix this at a system level,or is this something going wrong with each individual process?

很难说因为它未知在协议级别发生了什么.基本上,read(2)将无限期地阻止提供: –

> TCP连接保持打开状态.
>您希望至少有1个字节的数据到达.
>发件人尚未准备好向您发送数据.

现在,可能是这个过程出了问题,例如另一端在发送更多数据之前期待您的响应,或者另一端的先前响应期望SVN在请求更多数据之前做其他事情.例如,假设有一个错误响应,它会强制客户端重新发送一些信息.

您无法正常修复此问题,因为您无法根据信息确定此数据的发件人期望您执行的操作.但是,有一些可能的方法可以避免问题并进行报告.

>不是在简单阻塞模式下使用wait,而是在父进程中运行wait并配置警报.现在,当进程无法在一段固定的时间内完成时,您可以将其杀死并报告发生这种情况.一种廉价的方法是改变subprocess.Popen来调用timeout命令.
>修改读取以便设置读取超时套接字选项.您可以通过更改代码来执行此操作,或者 – 使用插入器覆盖默认套接字系统调用以向接收器添加超时.这两者都不是微不足道的.这可能会导致svn以意想不到的方式运行.

Is there something fundamentally different about how OS X and Linux handle read calls that I need to know to avoid infinitely-hanging processes?

我不知道这个问题的答案,但是如果两者的行为都是正确的,那么它们的行为应该是相同的.如果您尝试从尚未准备发送数据的套接字读取数据,则无限期阻止该流是预期的行为.

总的来说,我认为你最好的攻击选择是期望你的svn命令在特定的时间段内完成.如果它没有杀死它并报告你这样做了.

猜你在找的Linux相关文章