按顺序重新加载systemd / gunicorn / flask工作线程以进行配置更改

时间:2017-08-01 22:05:14

标签: python flask gunicorn systemd

我需要强制重新加载应用以获取配置更改。我正在使用systemd来踢一个运行烧瓶app的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烧瓶工人线程?

应用程序的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工作线程并重新启动它们。

我想避免杀死正在处理repsonses的线程。

理想情况下,在处理完每个响应后,线程会检查是否需要退出。我知道我可以在每个烧瓶API方法中执行此操作,但有没有更好的方法一次将所有工作线程转换为新配置?

我不希望sysctl restart app.service因为它会杀死所有线程并创建一个没有工作人员活动的死时间。 我希望每个步骤都能独立终止和重新加载,因此总会有一些现场工作人员。

我考虑过的一些选项:

  1. 使用app-reload.py获取app pid列表,然后逐个删除它们。 Gunicorn会因为死亡而重新开始。可以终止正在进行的请求。

  2. 处理完每个事件后,检查app-reload.py创建的文件是否存在,如果存在,则终止。

  3. 我假设必须有办法将工作人员从一个配置迁移到另一个配置而不会造成服务死角。

1 个答案:

答案 0 :(得分:1)

RTM再次获胜。

http://docs.gunicorn.org/en/stable/signals.html

  

HUP:重新加载配置,使用a启动新的工作进程   新配置并优雅地关闭旧工作人员。如果   应用程序未预加载(使用preload_app选项),Gunicorn   还将加载它的新版本。

所以最终结果就是在systemd app.path中的结果:

[Unit]
Description=app-restart
After=network.target

[Service]
Type=oneshot
User=root
Group=root
ExecStart=/bin/kill -s HUP $(cat /run/app/pid)
PrivateTmp=false

或者,也可以依赖app.system包含ExecReload行并使用的事实:

ExecReload=/bin/systemctl reload app