重新启动/重新加载服务器后,从wsgi启动的进程仍在运行

时间:2012-08-15 18:47:50

标签: python apache python-3.x mod-wsgi

在Ubuntu 12.04上使用mod_wsgi for python 3。

我有一个WSGI应用程序(实际上只是一个脚本)恰好用Popen为每个用户会话启动一个外部程序(它实际上是一个小型GTK程序,我正在试验它的HTML5后端)。

客户端有一个Javascript循环,每隔几秒就向WSGI发送一个“keep alive”信号。如果WSGI在一段时间内没有收到会话的任何信号,那么它将终止相关进程(并删除会话)。

这很有效,除非我重新启动/重新加载Apache或编辑WSGI脚本(AFAIK自动重新加载应用程序)。 如果我这样做,子进程不会被杀死。他们仍然运行(他们不是僵尸),我所能做的就是手动杀死它们(WSGI失去了以前的会话,所以它不会杀死任何“旧”进程)。

所以我想要以下其中一项:

  • 一种注意服务器正在从WSGI端停止/重新启动/重新加载的方法,以便它可以在知道它们时清理它的子进程
  • 产生的进程应该用mod_wsgi消失(当mod_wsgi被杀死/重新加载时,似乎子进程被重新连接到Init)

这是我使用的VirtualHost:

<VirtualHost *:80>

WSGIDaemonProcess deckard_qh user=deckard group=deckard threads=5
WSGIScriptAlias / /home/deckard/wsgi/deckard_qh.wsgi
Alias /ressources /home/deckard/ressources

<Directory /home/deckard/wsgi>
    WSGIProcessGroup deckard_qh
    WSGIApplicationGroup %{GLOBAL}
    Order deny,allow
    Allow from all
</Directory>

<Directory /home/deckard/ressources>
    Order deny,allow
    Allow from all
</Directory>

我尝试添加WSGIProcessGroup deckardWSGIApplicationGroup %{GLOBAL}(根据this answer),但它没有改变任何内容。 我还在WSGI脚本的开头添加了os.setsid(),但没有结果。

2 个答案:

答案 0 :(得分:2)

这只是一个草图,但是一个简单的解决方案(孩子们管理自己,我最喜欢的一种解决方案!)会给Popen进程添加一个kill超时,所以如果他们没有在5中收到'keep alive'分钟(或者你认为是正确的)他们会保存状态(如果适用)并终止?

我猜测gtk_main_quit()将是你用来终止事件循环的东西,但是如果我离开了基础,替换任何会终止你的子进程=)另外,我猜测gtk偶数循环可能有它的自己的计时器功能,它将是一个与线程不同的实现,但我想测试我发布的内容。

import datetime
from threading import Timer

# dummy timestamp for testing, gong should be the 
# timestamp of the last keepAlive signal
gong = datetime.datetime(2012, 8, 16, 16, 3, 18, 341121)  

#seconds before kill check is performed
idle = 5

def bringOutYourDead():
    """If the last keep alive time stamp is more than 5 minutes ago, I am Audi 500."""
    stoneDeadIn =  5
    if datetime.datetime.now() - datetime.timedelta(minutes=stoneDeadIn) >= gong:
        # I used print for whatever command for testing
        print('save_state_or_whatever()')
        print('gtk_main_quit()')
    else:
        print("I'm not dead yet!'")
    # recurse this as you see fit

dung = Timer(idle, bringOutYourDead)
dung.start()

答案 1 :(得分:1)

您是否尝试过sudo service apache2 graceful

  

USR1或优雅信号导致父进程建议孩子在他们当前请求后退出(或者如果他们没有提供任何东西则立即退出)。父级重新读取其配置文件并重新打开其日志文件。当每个孩子去世时,父母将其替换为新一代配置中的孩子,该孩子立即开始提供新请求。

http://httpd.apache.org/docs/2.4/stopping.html#graceful