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.
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
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
: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:
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