Arch-Linux

gunicorn 19.2 無法以 18.0 配置啟動

  • February 24, 2015

我有一個在 nginx 後面執行 gunicorn/Django 的開發伺服器。作為更廣泛的伺服器環境更新的一部分,我嘗試將 gunicorn 從 18.0 升級到 19.2.1,但該服務將不再啟動。(伺服器正在執行 Arch,因此使用 systemctl。)

gunicorn 配置是由不再由我們支配的人完成的,並且不太了解 gunicorn,我無法修復甚至定位問題,所以我恢復到版本 18.0,它現在可以工作。但是,我想最終對其進行升級,並將配置設置為可以正常工作的形狀。我感覺目前的配置不是最理想的或多餘的,但我無法確定:-)。

環境(或 gunicorn 執行的 virtualenv)沒有任何變化,只有 gunicorn 本身被升級。Systemctl 產生了這個錯誤systemctl start gunicorn

● gunicorn.service - gunicorn daemon (production)
  Loaded: loaded (/usr/lib/systemd/system/gunicorn.service; enabled)
  Active: failed (Result: resources) since Tue 2015-02-17 20:55:41 UTC; 8s ago
 Process: 2837 ExecStop=/bin/kill -s QUIT $MAINPID (code=exited, status=0/SUCCESS)
 Process: 9608 ExecReload=/bin/kill -s HUP $MAINPID (code=exited, status=0/SUCCESS)
 Process: 5353 ExecStart=/home/django/gunicorn/run.sh (code=exited, status=0/SUCCESS)
Main PID: 24876 (code=exited, status=0/SUCCESS)

Feb 17 20:55:41 ashima systemd[1]: PID file /home/django/gunicorn/gunicorn.pid not readable (yet?) after start.
Feb 17 20:55:41 ashima systemd[1]: gunicorn.service never wrote its PID file. Failing.
Feb 17 20:55:41 ashima systemd[1]: Failed to start gunicorn daemon (production).
Feb 17 20:55:41 ashima systemd[1]: Unit gunicorn.service entered failed state.

嘗試run.sh從 shell 手動執行包含在(粘貼在下面)中的 gunicorn 命令,它只是立即退出而沒有產生任何錯誤,退出程式碼為 0。沒有記錄任何內容。事實上,我的前任在日誌文件增長到驚人的大小後不久就禁用了 gunicorn 日誌記錄,但這是另一天的問題。

以下是相關文件的內容:

/usr/lib/systemd/system/gunicorn.service:

[Unit]
Description=gunicorn daemon

[Service]
Type=forking
PIDFile=/home/django/gunicorn/gunicorn.pid
User=django
WorkingDirectory=/home/django/[name_withheld]/project
ExecStart=/home/django/gunicorn/run.sh
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=false

[Install]
WantedBy=multi-user.target

/home/django/gunicorn/run.sh:

#!/bin/bash

set -e

cd /home/django/[name_withheld]/project
source /home/django/.venv/bin/activate
exec gunicorn -p /home/django/gunicorn/gunicorn.pid -c /home/django/gunicorn/config.py -e HTTPS=on [name_withheld]_site.wsgi:application

/home/django/gunicorn/config.py:

bind = 'unix:/tmp/gunicorn.sock'
backlog = 2048
workers = 16
worker_class = 'egg:gunicorn#sync'
worker_connections = 1000
timeout = 30
keepalive = 2
debug = False
spew = False
daemon = True
pidfile = None
umask = 0755
user = None
group = None
tmp_upload_dir = None
raw_env = 'HTTPS=on'
errorlog = '-'
loglevel = 'info'
accesslog = None
proc_name = None

def post_fork(server, worker):
   server.log.info("Worker spawned (pid: %s)", worker.pid)

def pre_fork(server, worker):
   pass

def pre_exec(server):
   server.log.info("Forked child, re-executing.")

def when_ready(server):
   server.log.info("Server is ready. Spawning workers")

(在發佈到問題的評論中,我必須特別指出skarap的評論,因為它通過使 gunicorn 正確輸出錯誤幫助我自己找到解決方案。我希望我能為此獎勵部分賞金;轉換對答案的評論還不是一個完整的答案,但它確實有很大幫助。)

原來這是配置文件中有問題的行:

worker_class = 'egg:gunicorn#sync'

它導致了這個錯誤:

Error: class uri 'egg:gunicorn#sync' invalid or not found: 

[Traceback (most recent call last):
 File "/home/django/.venv/lib/python2.7/site-packages/gunicorn/util.py", line 113, in load_class
   return pkg_resources.load_entry_point(dist, section, name)
 File "/home/django/.venv/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg/pkg_resources.py", line 318, in load_entry_point
   return get_distribution(dist).load_entry_point(group, name)
 File "/home/django/.venv/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg/pkg_resources.py", line 2220, in load_entry_point
   raise ImportError("Entry point %r not found" % ((group,name),))
ImportError: Entry point ('gunicorn.workers', 'sync') not found
]

將其替換為worker_class = 'sync'修復了 ImportError 並因此解決了問題。在 18.0 -> 19.2.1 升級中不需要其他配置更改。

我打算報告 gunicorn 的文件似乎存在問題,因為在撰寫本文時,v19.2.1 的文件仍然聲明egg:gunicorn#[worker]語法有效。(那裡的範例使用 gevent,但看起來它應該適用於其他類型)。誰知道,它在某些情況下可能是有效的,但在我的(virtualenv 中的 gunicorn,使用 pip 安裝)中,它不是。

引用自:https://serverfault.com/questions/669416