【发布时间】:2017-08-01 22:05:14
【问题描述】:
我需要强制重新加载应用以获取配置更改。我正在使用 systemd 来启动运行烧瓶应用程序的 gunicorn。
我在 /var/run/xx.conf 文件中获取配置更改,该文件由 systemd/service/app.path 监视:
[Path]
PathChanged=/var/run/app.conf
[Unit]
Description=app-restart
以及相应的app.system:
[Unit]
Description=app-restart
After=network.target
[Service]
Type=oneshot
PIDFile=/run/app-restart/pid
User=root
Group=root
ExecStart=/usr/bin/app-reload.py
PrivateTmp=false
EnvironmentFile=-/etc/environment
[Install]
WantedBy=multi-user.target
问题是——如何优雅地终止每个 gunicorn flask 工作线程?
应用的 systemd 服务使用:
[Unit]
Description=app gunicorn daemon
After=network.target
[Service]
PIDFile=/run/app/pid
User=ubuntu
Group=www-data
WorkingDirectory=/opt/app
ExecStart=/usr/local/bin/gunicorn --bind unix:/var/tmp/app.sock -m 007 --workers=2 -t 400 --backlog 2048 --log-config=/etc/app/log.cfg --log-level=DEBUG app
Restart=always
RestartSec=15
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
PrivateTmp=false
EnvironmentFile=-/etc/environment
[Install]
WantedBy=multi-user.target
这样我就可以杀死 gunicorn 工作线程并重新启动它们。
我想避免杀死正在处理响应的线程。
理想情况下,在处理完每个响应后,线程会检查它是否需要退出。我知道我可以在每个烧瓶 API 方法中执行此操作,但有没有更好的方法将所有工作线程一次转换到新配置?
我不想sysctl restart app.service,因为这会杀死所有线程并造成没有工作人员处于活动状态的死区时间。
我希望每个胎面都能独立终止和重新加载,这样总有一些活的工人。
我考虑过的一些选项:
使用 app-reload.py 获取应用程序 pid 列表,并一次将它们杀死一个。 Gunicorn 会在它死后重新启动。可以终止正在进行的请求。
处理完每个事件后,检查由 app-reload.py 创建的文件是否存在,如果存在,则终止。
我假设必须有一种方法可以将工作人员从一个配置迁移到另一个配置,而不会造成服务死点。
【问题讨论】:
标签: python flask gunicorn systemd