我正在使用python进程从端口提取数据,这是在Ubuntu服务器上作为upstart作业启动的。数据使用TCP发送,每个客户端发送一个相对较小的信息串:
upstart配置:
start on runlevel [2345]
stop on runlevel [!2345]
respawn
respawn limit 3 5
setuid takeaim
setgid takeaim
exec /home/takeaim/production/deploy/production/update_service_demon.sh
update_service_demon.sh脚本(我发现更容易调试将其从新贵中分离出来):
#!/bin/bash
# Make sure we're in the right virtual env and location
source /home/takeaim/.virtualenvs/production/bin/activate
source /home/takeaim/.virtualenvs/production/bin/postactivate
cd /home/takeaim/production
exec python drupdate/dr_update_service.py
python脚本(它将实际工作分发给芹菜工人):
from collections import defaultdict
import select
import socket
from django.conf import settings
from drupdate.tasks import do_dr_update
def create_server_socket():
"""Set up the and return server socket"""
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setblocking(0)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('0.0.0.0', settings.DRUPDATE['PORT']))
server_socket.listen(settings.DRUPDATE['MAX_CONNECT_REQUESTS'])
return server_socket
def serve(echo_only=False):
message_length = settings.DRUPDATE['MSG_LENGTH']
message_chunks = defaultdict(list)
server_socket = create_server_socket()
inputs = [server_socket]
while inputs:
readable, writable, exceptional = select.select(inputs, [], inputs)
for sock in readable:
if sock is server_socket:
client_socket, address = server_socket.accept()
client_socket.setblocking(0)
inputs.append(client_socket)
else:
chunk = sock.recv(message_length)
if chunk:
message_chunks[sock].append(chunk)
else:
# This client_socket is finished, hand off message for processing
message = ''.join(message_chunks[sock])
if echo_only:
print(message)
else:
do_dr_update.delay(message)
inputs.remove(sock)
sock.close()
for sock in exceptional:
inputs.remove(sock)
sock.close()
if sock is server_socket:
# replace bad server socket
server_socket = create_server_socket()
inputs.append(server_socket)
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Process incoming DR messages")
parser.add_argument('--echo', help='Just echo incoming messages to the console - no updates will take place',
dest='echo_only', action='store_true', default=False)
args = parser.parse_args()
serve(echo_only=args.echo_only)
尽管重新启动,该过程时不时地消失。我不愿意重新启动无限制,除非我能理解为什么这个过程会消失。手动重启工作正常......直到它再次消失。它可以持续数天然后消失。
找出正在发生的事情的最佳方法是什么?
答案 0 :(得分:2)
为系统添加足够的日志记录,以便在发生故障后分析跟踪。
以下是按详细程度记录的一些建议:
使用以下代码段替换exec python drupdate/dr_update_service.py
调用,该代码段会在退出时将python进程的退出代码记录到syslog中。退出代码可以提供有关进程如何终止的一些线索。例如,如果过程通过信号终止,则退出代码将是> = 128。
python drupdate/dr_update_service.py || logger "He's dead Jim, exit code $?"
在try/except
的{{1}}来电中添加server
个屏蔽。在异常处理程序中,将回溯打印到文件或记录子系统。
如果上述方法无法提供线索,请通过调用__main__
包装整个脚本,并将输出转移到日志文件中。这将跟踪程序,其参数和返回代码所产生的整个系统调用集。这将有助于调试可能与返回错误的系统调用相关的问题。应用此方法会降低您的流程并产生大量输出,这可能反过来会改变您的程序行为并掩盖潜在问题。