使用systemd部署gunicorn和uvicorn

使用systemd部署gunicorn和uvicorn

您能告诉我为什么工作类在使用时uvicorn不加载吗?gunicornsystemd

当我发起gunicorn这样的事情时:

/usr/local/bin/gunicorn --bind 127.0.0.1:5045 --forwarded-allow-ips="x.x.x.x" --workers 1 --worker-class uvicorn.workers.UvicornWorker --pid /home/xxx/ip-spotlight/run/pid/ip-spotlight.webapp.glass.pid --error-logfile /var/log/ip-spotlight/ip-spotlight.webapp.glass.error.log --access-logfile /var/log/ip-spotlight/ip-spotlight.webapp.glass.access.log --capture-output glass:app

它工作正常:

[2019-12-10 22:08:55 +0100] [1288] [INFO] Starting gunicorn 20.0.4
[2019-12-10 22:08:55 +0100] [1288] [INFO] Listening at: http://127.0.0.1:5045 (1288)
[2019-12-10 22:08:55 +0100] [1288] [INFO] Using worker: uvicorn.workers.UvicornWorker
[2019-12-10 22:08:55 +0100] [1293] [INFO] Booting worker with pid: 1293
[2019-12-10 22:08:56 +0100] [1293] [INFO] Started server process [1293]
[2019-12-10 22:08:56 +0100] [1293] [INFO] Waiting for application startup.
[2019-12-10 22:08:56 +0100] [1293] [INFO] Application startup complete.

但是,当使用systemd它作为服务运行时,其配置如下:

[Unit]
Description=webapp-glass
Requires=network-online.target
After=network-online.target

[Service]
User={{ username }}
WorkingDirectory={{ dir.app }}/ip-spotlight/code/web/glass
EnvironmentFile=-/etc/sysconfig/webapp-glass
ExecStart=/usr/local/bin/gunicorn  $OPTIONS  glass:app
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
PrivateTmp=true
Restart=on-failure

[Install]
WantedBy=multi-user.target

哪里/etc/sysconfig/webapp-glass

OPTIONS="--bind 127.0.0.1:5045 --forwarded-allow-ips="x.x.x.x" --workers 1 --worker-class uvicorn.workers.UvicornWor
ker --pid /home/xxx/ip-spotlight/run/pid/ip-spotlight.webapp.glass.pid --error-logfile /var/log/ip-spotlight/ip-spotlight.webapp.glass.error.log --acc
ess-logfile /var/log/ip-spotlight/ip-spotlight.webapp.glass.access.log --capture-output"

日志说:

Dec 10 22:16:54 nl-ams02c-ispbgp01.xxx.xxx systemd[1]: Started webapp-glass.
Dec 10 22:16:54 nl-ams02c-ispbgp01.xxx.xxx gunicorn[1794]: [2019-12-10 22:16:54 +0100] [1794] [INFO] Starting gunicorn 20.0.4
Dec 10 22:16:54 nl-ams02c-ispbgp01.xxx.xxx gunicorn[1794]: [2019-12-10 22:16:54 +0100] [1794] [INFO] Listening at: http://127.0.0.1:5045 (1794)
Dec 10 22:16:54 nl-ams02c-ispbgp01.xxx.xxx gunicorn[1794]: [2019-12-10 22:16:54 +0100] [1794] [INFO] Using worker: sync
Dec 10 22:16:54 nl-ams02c-ispbgp01.xxx.xxx gunicorn[1794]: [2019-12-10 22:16:54 +0100] [1798] [INFO] Booting worker with pid: 1798

它说Using worker: sync(而不是Using worker: uvicorn.workers.UvicornWorker)这是错误的,因为该应用程序基于 ASGI,因此它会崩溃,因为它需要uvicorn.

您能否善意地指出为什么没有加载正确的工作类?

答案1

Systemd 环境文件和声明不使用 shell 语法。它只支持一些有限的引用和扩展。因此,"--bind 127.0.0.1:5045 --forwarded-allow-ips="x.x.x.x" --..."删除引号后只是--bind 127.0.0.1:5045 --forwarded-allow-ips=x.x.x.x --...在 shell 中(假设默认 IFS,并且没有文件名扩展),这与 systemd 中的情况不同EnvironmentFile

另请注意,您打算执行的操作(在带引号的字符串内添加引号)是不必要的,并且无论如何都不会按照您想象的方式工作。 shell 会看到的是带引号的字符串,--bind 127.0.0.1:5045 --forwarded-allow-ips=后面跟着不带引号的字符串,x.x.x.x后面跟着带引号的字符串--workers 1 --worker-class uvicorn.workers.UvicornWorker --pid...,它会简单地将它们连接起来。但是,文件名扩展不会在变量赋值中发生,因此只有在其中存在空格或制表符时才会出现问题x.x.x.x(不用担心,因为它是 IP)。该行应该是:

OPTIONS="--bind 127.0.0.1:5045 --forwarded-allow-ips=x.x.x.x --workers 1 --worker-class uvicorn.workers.UvicornWorker --pid /home/xxx/ip-spotlight/run/pid/ip-spotlight.webapp.glass.pid --error-logfile /var/log/ip-spotlight/ip-spotlight.webapp.glass.error.log --access-logfile /var/log/ip-spotlight/ip-spotlight.webapp.glass.access.log --capture-output"

这对于 shell 和 systemd 都有效。

相关内容