重新启动Django服务器时,如何防止Django进程生成的websockify进程被杀死?

2024-04-29 16:08:35 发布

您现在位置:Python中文网/ 问答频道 /正文

请注意,Django服务器是Daphne,但websockify命令与Daphne通道无关

在Django视图中,我有以下过于简化的代码:

def openvnc_connection(request):
    Popen(['websockify'. "--run-once", "--daemon", "--timeout", "30", "--idle-timeout", "60", "--cert", ...])
    ...

问题是,当我部署代码时,涉及重新启动Daphne worker服务,websockify进程也会被终止,导致任何活动的vnc连接都会被删除

我知道websockify进程是django进程的子进程,它因此被杀死

我已经尝试过类似于double-forksimilar stuff的分离子进程的方法,但它们似乎不起作用,而且重新启动Daphne worker时websockify进程仍然会被终止

试用双叉:

def spawnDaemon(port, target):
    import os, sys, subprocess
    # do the UNIX double-fork magic, see Stevens' "Advanced
    # Programming in the UNIX Environment" for details (ISBN 0201563177)
    try:
        pid = os.fork()
        if pid > 0:
            # parent process, return and keep running
            return
    except Exception as e:
        print(sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror))
        sys.exit(1)

    os.setsid()

    # do second fork
    try:
        pid = os.fork()
        if pid > 0:
            # exit from second parent
            sys.exit(0)
    except Exception as e:
        print(sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror))
        sys.exit(1)

    # do stuff
    Popen(['websockify'. "--run-once", "--daemon", "--timeout", "30", "--idle-timeout", "60", "--cert", ...])

    # all done
    os._exit(os.EX_OK)

Tags: djangorun代码进程osdefsysexit
1条回答
网友
1楼 · 发布于 2024-04-29 16:08:35

所以。。。我绕了一大圈,试图通过另一个python代码生成websockify,该代码实现了双分叉:

def double_fork():
    try:
        pid = os.fork()
        if pid > 0:
            # parent process, return and keep running
            return
    except Exception as e:
        sys.exit(1)

    os.setsid()

    # do second fork
    try:
        pid = os.fork()
        if pid > 0:
            # exit from second parent
            sys.exit(0)
    except Exception as e:
        logger.error("fork #2 failed: %d (%s)" % (e.errno, e.strerror))
        sys.exit(1)

    from websockify.websocketproxy import WebSocketProxy, LibProxyServer
    WebSocketProxy(run_once=True, timeout=30, idle_timeout=60, target_host=sys.argv[1], target_port=sys.argv[2], listen_port=sys.argv[3],
            cert=cert, key=key, daemon=False).start_server()

这导致了能够双分叉,但在我运行sudo systemctl restart ...时仍然被杀死,然后进一步搜索发现这个answer,它对我有效,只需要添加到服务块

KillMode=process

然后,我还尝试在没有新的python脚本的情况下使用double fork,只调用旧的Popen(...),我相信它也会产生一个守护进程,而且它也可以工作

相关问题 更多 >