如何诊断消失的端口监听器?

时间:2014-10-22 23:13:18

标签: python sockets ubuntu

我正在使用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)

尽管重新启动,该过程时不时地消失。我不愿意重新启动无限制,除非我能理解为什么这个过程会消失。手动重启工作正常......直到它再次消失。它可以持续数天然后消失。

找出正在发生的事情的最佳方法是什么?

1 个答案:

答案 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__包装整个脚本,并将输出转移到日志文件中。这将跟踪程序,其参数和返回代码所产生的整个系统调用集。这将有助于调试可能与返回错误的系统调用相关的问题。应用此方法会降低您的流程并产生大量输出,这可能反过来会改变您的程序行为并掩盖潜在问题。