进程在SQS调用中卡住

2 投票
1 回答
1636 浏览
提问于 2025-04-18 14:40

我有一个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/

Web应用在ssl.py的self._sslobj.do_handshake()处卡住了几个小时

如果函数执行太久,设置超时功能

撰写回答