更新如下:
我在一个不相关的脚本上经历了类似的问题,在不同的数据中心的Debian虚拟机上。
这看起来像这里描述的问题(和像问这个问题的人一样,我没有在服务器前configuration代理)。
与以下描述的主要区别在于,当我附加到挂起的进程时,我看到一个调用recvfrom而不是read :
$ 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
所以我仍然难住。 可悲的是,这个相关的问题也没有最终的答案。
(我也想知道这个问题是否是相关的,但是S3似乎不太可能不尊重Connection: close headers。)
我有几个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)
起初,我认为这只是由于缺less在Python脚本中设置读取超时的原因,但似乎并非如此,原因如下:
socket.setdefaulttimeout – 这是在Python 2.7中,但代码库必须兼容2.5)。 svn up --non-interactive进程(使用subprocess.Popen ,这是值得的)。 那个SVN过程的情况是类似的 –
Python正在等待SVN:
$ strace -p 28034 Process 28034 attached - interrupt to quit wait4(28127,
而SVN正在等待read电话完成:
$ 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在目录被更新;基于他们的网站,我认为这是redirect到telecommunity.com)
其他可能相关的要点:
svn:externals的含义是什么; 这是在我的时间之前build立的。 ifconfig没有丢弃的数据包)。 我想这表明一个networkingconfiguration问题,但我不知道从哪里开始。 所以我想我的问题是:
read调用,我需要知道的以避免无限悬挂进程,有什么根本的不同吗? 我可以在系统级别解决这个问题吗,还是每个进程都有问题?
这很难说,因为它在协议层面上是未知的。 read(2)基本上将无限期地提供: –
现在,这个过程可能是有问题的,比如另一端在发送更多的数据之前就要等待你的响应,或者另一端的响应预期SVN在请求更多的数据之前做其他的事情 。 假设例如一个错误响应回来,这应该强制客户端重新发送一些信息。
你不能修复这个优雅,因为它不可能的信息,你必须确定这个数据的发送者希望你做的事情。 但是,有几种可能的方法来避免这个问题并报告。
wait ,运行wait并在父进程中configuration一个警报。 现在,当进程无法在一段固定的时间内完成,你可以杀死它并报告发生的事情。 一个便宜的方法是修改subprocess.Popen来调用timeout命令。 socket系统调用,并为接收方添加超时。 这两个都不是微不足道的。 这可能会导致svn以意想不到的方式行事。 对于OS X和Linux如何处理读取调用,我需要知道的以避免无限悬挂进程,有什么根本的不同吗?
我不知道这个问题的答案,但是如果两者都是正确的,他们都应该以同样的方式行事。 如果您尝试从尚未准备好发送数据的套接字读取数据,则无限期地阻止数据stream是预期的行为。
总的来说,我认为你最好的select是希望你的svn命令在特定的时间内完成。 如果它不杀它,并报告你这样做。
我想我已经找出了上述的问题,而且大部分的谜团都来自于我对服务器上发生的事情的误解。
有以下基本问题:
我在这里留下这个答案来解释发生了什么,但是我会接受马修的,因为他对于实际可能的问题是正确的。