进程在SQS调用中卡住
我有一个Python脚本,它会在一个循环中检查SQS(简单队列服务)里的消息,然后停止。这个脚本每隔几分钟会被一个定时任务(cron job)重新启动,以防它没有在运行。
#start def main():
------For i from 1 to 100:
-------------Check SQS for new message[establish connections to SQS] # long polling not used, Receive message wait time set to 0.
-------------If new job found:
--------------------ProcessIt()
# end
我发现这个脚本在EC2实例上运行几天后,就变得无效了,无法检查SQS里的新消息。
当我用lsof命令查看这个进程的PID,并只关注SQS的连接时,发现所有连接都处于CLOSE_WAIT状态。解决这个问题的方法就是手动杀掉并重启这个脚本进程。所以,看起来定时任务根本无法重新启动这个脚本,因为它一直在运行,并且卡在了与SQS的连接上:
ip-10-x-y-z:~ # lsof -p 9018 | grep "72.21" ld-linux. 9018 root 7u IPv4 474699439 0t0 TCP ip-10-x-y-z.ec2.internal:58211->72.21.202.145:https (CLOSE_WAIT) ld-linux. 9018 root 10u IPv4 474699560 0t0 TCP ip-10-x-y-z.ec2.internal:53428->72.21.194.47:https (CLOSE_WAIT) ld-linux. 9018 root 12u IPv4 474701017 0t0 TCP ip-10-x-y-z.ec2.internal:52166->72.21.214.70:https (CLOSE_WAIT) ld-linux. 9018 root 18u IPv4 474694555 0t0 TCP ip-10-x-y-z.ec2.internal:57267->72.21.202.145:https (CLOSE_WAIT) ld-linux. 9018 root 22u IPv4 474694573 0t0 TCP ip-10-x-y-z.ec2.internal:57271->72.21.202.145:https (CLOSE_WAIT) ld-linux. 9018 root 39u IPv4 474701031 0t0 TCP ip-10-x-y-z.ec2.internal:52170->72.21.214.70:https (CLOSE_WAIT)
我知道我应该使用长轮询(long polling),但我还是想知道为什么这个进程会卡住,自己又无法恢复。我使用的是Boto 2.23。
任何建议都很有帮助。
1 个回答
1
在使用gdb调试的时候,我发现我的程序卡住了,下面是它的错误追踪信息:
(gdb) pystack
~/mypackage/lib/python2.6/ssl.py (293): do_handshake
~/mypackage/lib/python2.6/ssl.py (120): __init__
~/mypackage/lib/python2.6/ssl.py (350): wrap_socket
~/mypackage/lib/python2.6/site-packages/boto/https_connection.py (118): connect
~/mypackage/lib/python2.6/httplib.py (725): send
~/mypackage/lib/python2.6/httplib.py (764): _send_output
~/mypackage/lib/python2.6/httplib.py (892): endheaders
~/mypackage/lib/python2.6/httplib.py (937): _send_request
~/mypackage/lib/python2.6/httplib.py (899): request
~/mypackage/lib/python2.6/site-packages/boto/connection.py (902): _mexe
~/mypackage/lib/python2.6/site-packages/boto/connection.py (1063): make_request
~/mypackage/lib/python2.6/site-packages/boto/connection.py (1138): get_object
~/mypackage/lib/python2.6/site-packages/boto/sqs/connection.py (355): get_queue
~/mypackage/lib/python2.6/site-packages/sqs/SQSHelper.py (96): __init__
~/mypackage/sqs/SQSWrapper.py (1229): main
~/mypackage/sqs/SQSWrapper.py (1367): <module>
从中可以看出,我的脚本在调用SQS的get_queue()这个接口时卡住了。
看起来问题出在Python 2.6的ssl握手功能上,这个问题在Python 2.7中已经修复了。不过,有人也在Python 2.7中报告了同样的问题[可以查看下面的链接]。为了修复这个问题,我打算使用Python 2.7,并在我的SQS包装代码中给SQS的API设置几分钟的超时时间。
以下链接帮助我找到了问题的根源和解决办法:
http://bugs.python.org/issue5103
http://hg.python.org/cpython/rev/ce4916ca06dd/