使用结构和主管部署 Web 应用程序 - SIGHUP 导致服务器终止
Posted
技术标签:
【中文标题】使用结构和主管部署 Web 应用程序 - SIGHUP 导致服务器终止【英文标题】:Deploying web application with fabric and supervisor - SIGHUP causes server to be terminated 【发布时间】:2012-10-24 13:38:14 【问题描述】:我们正在使用 supervisor 来部署一个 python web 应用程序。在部署时,Web 应用程序通过 buildout 安装在服务器上,并使用collective.recipe.supervisor 创建运行主管的脚本。此脚本在部署过程结束时由结构脚本调用。问题是,当部署脚本完成时,会向进程发送一个 SIGHUP 信号,这会导致主管重新启动(根据这一行:https://github.com/Supervisor/supervisor/blob/master/supervisor/supervisord.py#L300),但由于某种原因,Web 应用程序在它之后没有重新启动被终止。以下后没有日志输出:
2012-10-24 15:23:51,510 WARN received SIGHUP indicating restart request
2012-10-24 15:23:51,511 INFO waiting for app-server to die
2012-10-24 15:23:54,650 INFO waiting for app-server to die
2012-10-24 15:23:57,653 INFO waiting for app-server to die
2012-10-24 15:24:00,657 INFO waiting for app-server to die
2012-10-24 15:24:01,658 WARN killing 'app-server' (28981) with SIGKILL
2012-10-24 15:24:01,659 INFO stopped: app-server (terminated by SIGKILL)
所以我有两个问题。第一个是,有人知道为什么主管会在 SIGHUP 上重新启动吗?我找不到任何解释,也没有命令行选项可以关闭此行为。第二个问题是,我们如何解决我们面临的问题?我们尝试使用 nohup 启动主管,但仍然收到 SIGHUP。奇怪的是,当我登录服务器、手动启动主管并注销时,这不会发生。
这是 buildout 生成的主管脚本:
#!/usr/bin/python2.6
import sys
sys.path[0:0] = [
'/home/username/.buildout/eggs/supervisor-3.0b1-py2.6.egg',
'/home/username/.buildout/eggs/meld3-0.6.9-py2.6.egg',
'/home/username/.buildout/eggs/distribute-0.6.30-py2.6.egg',
]
import sys; sys.argv.extend(["-c","/home/username/app_directory/parts/supervisor/supervisord.conf"])
import supervisor.supervisord
if __name__ == '__main__':
sys.exit(supervisor.supervisord.main())
这里是supervisor的配置文件,也是由buildout生成的:
[supervisord]
childlogdir = /home/username/app_directory/var/log
logfile = /home/username/app_directory/var/log/supervisord.log
logfile_maxbytes = 50MB
logfile_backups = 10
loglevel = info
pidfile = /home/username/app_directory/var/supervisord.pid
umask = 022
nodaemon = false
nocleanup = false
[unix_http_server]
file = /home/username/app_directory/supervisor.sock
username = username
password = apasswd
chmod = 0700
[supervisorctl]
serverurl = unix:///home/username/app_directory/supervisor.sock
username = username
password = apasswd
[rpcinterface:supervisor]
supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface
[program:app-server]
command = /home/username/app_directory/bin/gunicorn --bind 0.0.0.0:5000 app:wsgi
process_name = app-server
directory = /home/username/app_directory/bin
priority = 50
redirect_stderr = false
directory = /home/username/app_directory
在真正理解问题之前,我们不想安装补丁版本的主管,因此我们非常感谢您提供任何信息。
提前致谢
【问题讨论】:
【参考方案1】:在SIGHUP
上重新启动或重新加载是 linux 系统编程中的常见做法。问题是为什么在部署结束后您会收到SIGHUP
。由于 supervisor 正确地守护了自己(因为你可以启动它并注销它会工作),reload 信号可能会通过构建 bot 发送给 supervisor,表明 webapp 需要重新启动,因为代码已经改变。
因此主管启动应用关闭,以便使用新代码启动应用。但是应用程序不会在给定的超时时间内停止,并且主管决定该应用程序挂起并使用SIGKILL
终止它。
要解决问题,您需要教应用程序在主管要求时关闭。
【讨论】:
【参考方案2】:supervisord 文档明确指出,向 supervisord 进程发送 SIGHUP 将“停止所有进程,从它找到的第一个配置文件重新加载配置,然后重新启动所有进程”。
参考-http://supervisord.org/running.html#signal-handlers
也许您的流程行为不端;看起来主管多次尝试很好地关闭它,但后来决定需要硬杀:
process.py:560
# kill processes which are taking too long to stop with a final
# sigkill. if this doesn't kill it, the process will be stuck
# in the STOPPING state forever.
self.config.options.logger.warn(
killing %r (%s) with SIGKILL' % (self.config.name, self.pid))
self.kill(signal.SIGKILL)
也许 kill call 失败了?
【讨论】:
【参考方案3】:您可能遇到了这个错误:https://github.com/Supervisor/supervisor/issues/121
解决方法是降级 supervisord,直到在发布版本中修复。
【讨论】:
【参考方案4】:遇到完全相同的问题,降级到 3.0a10 解决了它。
【讨论】:
以上是关于使用结构和主管部署 Web 应用程序 - SIGHUP 导致服务器终止的主要内容,如果未能解决你的问题,请参考以下文章
未从主管 AWS Elasticbeanstalk 激活 Virtualenv
如何使用自定义项目文件夹结构在 Beanstalk 中部署 Go Web 应用程序