gunicorn 19.2 falha ao iniciar com a configuração 18.0

5

Eu tenho um servidor dev executando o gunicorn / Django por trás do nginx. Como parte de uma atualização de ambiente de servidor mais ampla, tentei atualizar o gunicorn de 18.0 para 19.2.1, mas o serviço não seria mais iniciado. (O servidor está executando o Arch e, portanto, usa o systemctl.)

A configuração do gunicorn foi feita por alguém que não está mais à nossa disposição, e não conhecendo muito bem o gunicorn, não consegui consertar ou mesmo localizar o problema, então voltei para a versão 18.0 e está funcionando por enquanto. No entanto, eu gostaria de atualizá-lo eventualmente e obter a configuração em uma forma onde funcionaria. Tenho a sensação de que a configuração atual é sub-ótima ou redundante, mas não tenho como saber com certeza: -).

Nada mudou no ambiente (ou no virtualenv em que o gunicorn está sendo executado), apenas o próprio gunicorn foi atualizado. Systemctl produziu esse erro em 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.

Tentando executar manualmente o comando gunicorn contido em run.sh (colado abaixo) do shell, ele simplesmente saiu imediatamente sem produzir nenhum erro, com um código de saída 0. Nada foi registrado. Na verdade, parece que meu predecessor desativou o gunicorn logando um tempo atrás depois que o arquivo de log cresceu para um tamanho alarmante, mas isso é um problema para outro dia.

Aqui está o conteúdo dos arquivos relevantes:

/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")
    
por JK Laiho 17.02.2015 / 22:40

1 resposta

1

(Dos comentários postados para a pergunta, eu devo chamar especialmente aquele por skarap , uma vez que me ajudou a encontrar uma solução por conta própria, fazendo com que o gunicorn produzisse erros corretamente. Eu gostaria de poder conceder uma recompensa parcial por isso; a conversão desse comentário em uma resposta ainda não seria uma resposta completa, mas ajudou substancialmente.)

Acontece que esta foi a linha problemática no arquivo de configuração:

worker_class = 'egg:gunicorn#sync'

Isso causou esse erro:

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
]

A substituição por worker_class = 'sync' corrigiu o ImportError e, portanto, o problema. Nenhuma outra alteração de configuração foi necessária no 18.0 - > 19.2.1 atualização.

Parece haver um problema com a documentação do gunicorn, que eu pretendo relatar, porque no momento em que escrevo isso, os documentos para v19.2.1 ainda afirmam que a sintaxe egg:gunicorn#[worker] é válida. (O exemplo lá usa gevent, mas parece que deveria se aplicar a outros tipos). Quem sabe, pode ser válido em algumas circunstâncias, mas no meu (gunicorn em um virtualenv, instalado com pip), não é.

    
por 24.02.2015 / 06:25