Gunicorn: OSError: [Errno 11] Recurso temporariamente indisponível na versão 19.8.1 (e 19.8.0) no Heroku

Criado em 29 mai. 2018  ·  14Comentários  ·  Fonte: benoitc/gunicorn

Estou executando um servidor Flask simples no Heroku:

web: gunicorn --worker-class eventlet -w 1 app:app --log-file=-

Está usando o Python 2.7.15 para compatibilidade com vários outros pacotes.

Parece que me deparei com uma duplicata desse problema há muito tempo, desde que o Heroku mudou para a v. 19.8.1. Algumas imagens (de alguns kb a alguns mb) não carregam; Eu tenho um site com muitas imagens (principalmente folhas de sprite para animação) e aparentemente uma seleção aleatória delas não será carregada a cada vez, cada uma lançando o seguinte erro (se as imagens forem armazenadas em cache de uma versão anterior, ela será carregada sem problemas) :

2018-05-29T09:24:36.216949+00:00 app[web.1]: [2018-05-29 09:24:36 +0000] [10] [ERROR] Socket error processing request. 2018-05-29T09:24:36.216969+00:00 app[web.1]: Traceback (most recent call last): 2018-05-29T09:24:36.216971+00:00 app[web.1]: File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/workers/async.py", line 66, in handle 2018-05-29T09:24:36.216972+00:00 app[web.1]: six.reraise(*sys.exc_info()) 2018-05-29T09:24:36.216974+00:00 app[web.1]: File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/workers/async.py", line 56, in handle 2018-05-29T09:24:36.216976+00:00 app[web.1]: self.handle_request(listener_name, req, client, addr) 2018-05-29T09:24:36.216978+00:00 app[web.1]: File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/workers/async.py", line 129, in handle_request 2018-05-29T09:24:36.216980+00:00 app[web.1]: six.reraise(*sys.exc_info()) 2018-05-29T09:24:36.216981+00:00 app[web.1]: File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/workers/async.py", line 112, in handle_request 2018-05-29T09:24:36.216983+00:00 app[web.1]: resp.write_file(respiter) 2018-05-29T09:24:36.216985+00:00 app[web.1]: File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/http/wsgi.py", line 403, in write_file 2018-05-29T09:24:36.216987+00:00 app[web.1]: if not self.sendfile(respiter): 2018-05-29T09:24:36.216989+00:00 app[web.1]: File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/http/wsgi.py", line 393, in sendfile 2018-05-29T09:24:36.216990+00:00 app[web.1]: sent += sendfile(sockno, fileno, offset + sent, count) 2018-05-29T09:24:36.216992+00:00 app[web.1]: File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/http/_sendfile.py", line 66, in sendfile 2018-05-29T09:24:36.216994+00:00 app[web.1]: raise OSError(e, os.strerror(e)) 2018-05-29T09:24:36.216996+00:00 app[web.1]: OSError: [Errno 11] Resource temporarily unavailable

estas são as outras versões no arquivo requirements.txt:

Flask==0.12.2 gunicorn==19.8.1 pymongo==3.6.1 flask_socketio==2.9.6 flask_cors==3.0.3 eventlet==0.22.1 gevent==1.2.2

Mudar o gunicorn para 19.7.1 parece resolver o problema; ele persiste com 19.8.0.
Tal como acontece com o problema semelhante de 2012, não é um problema de tempo limite de solicitação, pois o erro que gera é bastante imediato. Reverter para 19.7.1 corrigiu isso, então por enquanto vou ficar com isso, mas seria bom usar a versão mais recente. Parece que isso pode ser um problema específico do Heroku; Eu só notei no último mês, mas não consigo encontrar nenhuma informação sobre quando eles mudaram de versão.

Comentários muito úteis

Eu lutei com esse mesmo problema hoje, o dia todo. E eu _acho_ que finalmente consertei. Estou usando nginx, Flask, gunicorn com eventlet e docker.

Minha saída (relevante) pip freeze :

eventlet==0.23.0
Flask==1.0.2
greenlet==0.4.14
gunicorn==19.9.0

Meu comando gunicorn:
gunicorn -b 0.0.0.0:8000 --workers 1 --worker-class eventlet --log-level=DEBUG myapp.wsgi:app

O primeiro sintoma foram grandes carregamentos de arquivos estáticos jogando ERR_CONTENT_LENGTH_MISMATCH no navegador. Obviamente, isso quebrou o aplicativo, pois grandes bibliotecas JS estáticas não estavam sendo carregadas.

O segundo sintoma foi o nginx registrando o seguinte em error.log: upstream prematurely closed connection while reading upstream

Por fim, rastreei até um item de log do gunicorn:

Socket error processing request. - [in /usr/local/lib/python2.7/dist-packages/gunicorn/glogging.py:277]
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 66, in handle
    six.reraise(*sys.exc_info())
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 56, in handle
    self.handle_request(listener_name, req, client, addr)
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 129, in handle_request
    six.reraise(*sys.exc_info())
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 112, in handle_request
    resp.write_file(respiter)
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/http/wsgi.py", line 403, in write_file
    if not self.sendfile(respiter):
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/http/wsgi.py", line 393, in sendfile
    sent += sendfile(sockno, fileno, offset + sent, count)
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/http/_sendfile.py", line 66, in sendfile
    raise OSError(e, os.strerror(e))
OSError: [Errno 11] Resource temporarily unavailable

Minha solução final foi iniciar o gunicorn com o sinalizador --no-sendfile , e o problema desapareceu. Por quê? Não tenho certeza... Estou feliz que esteja funcionando.

Também vale a pena mencionar que, durante minha solução de problemas, fiz o meu melhor para que meu nginx.conf se parecesse com o exemplo encontrado aqui: http://docs.gunicorn.org/en/stable/deploy.html

Todos 14 comentários

Eu lutei com esse mesmo problema hoje, o dia todo. E eu _acho_ que finalmente consertei. Estou usando nginx, Flask, gunicorn com eventlet e docker.

Minha saída (relevante) pip freeze :

eventlet==0.23.0
Flask==1.0.2
greenlet==0.4.14
gunicorn==19.9.0

Meu comando gunicorn:
gunicorn -b 0.0.0.0:8000 --workers 1 --worker-class eventlet --log-level=DEBUG myapp.wsgi:app

O primeiro sintoma foram grandes carregamentos de arquivos estáticos jogando ERR_CONTENT_LENGTH_MISMATCH no navegador. Obviamente, isso quebrou o aplicativo, pois grandes bibliotecas JS estáticas não estavam sendo carregadas.

O segundo sintoma foi o nginx registrando o seguinte em error.log: upstream prematurely closed connection while reading upstream

Por fim, rastreei até um item de log do gunicorn:

Socket error processing request. - [in /usr/local/lib/python2.7/dist-packages/gunicorn/glogging.py:277]
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 66, in handle
    six.reraise(*sys.exc_info())
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 56, in handle
    self.handle_request(listener_name, req, client, addr)
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 129, in handle_request
    six.reraise(*sys.exc_info())
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 112, in handle_request
    resp.write_file(respiter)
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/http/wsgi.py", line 403, in write_file
    if not self.sendfile(respiter):
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/http/wsgi.py", line 393, in sendfile
    sent += sendfile(sockno, fileno, offset + sent, count)
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/http/_sendfile.py", line 66, in sendfile
    raise OSError(e, os.strerror(e))
OSError: [Errno 11] Resource temporarily unavailable

Minha solução final foi iniciar o gunicorn com o sinalizador --no-sendfile , e o problema desapareceu. Por quê? Não tenho certeza... Estou feliz que esteja funcionando.

Também vale a pena mencionar que, durante minha solução de problemas, fiz o meu melhor para que meu nginx.conf se parecesse com o exemplo encontrado aqui: http://docs.gunicorn.org/en/stable/deploy.html

Eu também encontro esse problema, 19.7.0 funciona bem

Isso ocorre imediatamente ou após o envio parcial de uma resposta longa?

Pode ser causa de arquivo estático

alguma atualização disso? Estou enfrentando o mesmo problema em 19.9.0

Tudo estava funcionando bem e de repente começou a acontecer.

@tilgovi me avise se precisar de alguma informação sobre isso. De repente esse problema começou a aparecer

Para mim, o problema foi devido ao trabalhador eventlet. Eu removi o eventlet e está tudo bem agora.

Eu encontro o mesmo problema. E a sugestão do @SaintSimmo funciona bem para mim. Esse problema ocorre imediatamente ao iniciar o download de um arquivo grande. Estou usando balão e eventlet. E o trabalho de download é feito por send_from_directory do Flask.
O gunicorn é iniciado no seguinte comando:
gunicorn --worker-class eventlet -w 1 -b 0.0.0.0:4000 upload:app
que dará o erro.
se "--no-sendfile" for adicionado ao comando, nenhuma mensagem de erro será enviada. Se o trabalho de download pode ser feito sem "sendfile", então quando esse "sendfile" deve ser usado?

gunicorn (versão 19.9.0) mesmo problema com eventlet

Em 19.9.0, a recomendação do @SaintSimmo de definir --no-sendfile também funcionou para mim.

Sim, o mesmo problema e depois de remover o eventlet worker está funcionando bem.

Quando inicio o servidor com este comando (gunicorn -w 1 -k eventlet -b 127.0.0.1:5000 wsgi:app) recebo as exceções abaixo e minha imagem fica truncada na resposta do cliente.
[ERROR] Erro de soquete ao processar a solicitação.
...
BlockingIOError: [Errno 11] Recurso temporariamente indisponível

Removendo a definição da classe trabalhadora, funciona.
gunicorn -w 1 -b 127.0.0.1:5000 wsgi:app

@jacebrowning e @SaintSimmo , confirmo que o parâmetro extra --no-sendfile no comando gunicorn é eficaz.

Isso geralmente ocorre devido ao nproc ser muito pequeno, você pode aumentar o número de nproc para o usuário que executa esse programa editando o arquivo ' /etc/security/limits.conf '.

Você está sofrendo com esse problema? Se você estiver usando o Python 3.4 ou superior, atualize sua versão do Gunicorn.

Eu tive o mesmo problema com --worker-class. Atualizei o gunicorn para 20.0.4 e o problema foi resolvido.

Mudar de classe trabalhadora para gevent funcionou para mim. --worker-class gevent

Esta página foi útil?
0 / 5 - 0 avaliações