您能告诉我为什么工作类在使用时uvicorn
不加载吗?gunicorn
systemd
当我发起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 都有效。