Gunicorn: OSError : [Errno 11] Ressource temporairement indisponible sur la version 19.8.1 (et 19.8.0) sur Heroku

Créé le 29 mai 2018  ·  14Commentaires  ·  Source: benoitc/gunicorn

J'utilise un simple serveur Flask sur Heroku :

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

Il utilise Python 2.7.15 pour la compatibilité avec divers autres packages.

Il me semble avoir rencontré un doublon de ce problème il y a longtemps depuis que Heroku est passé à la v. 19.8.1. Certaines images (de quelques Ko à quelques Mo) ne se chargent pas ; J'ai un site avec beaucoup d'images (principalement des feuilles de sprite pour l'animation) et apparemment une sélection aléatoire d'entre elles ne se chargera pas à chaque fois, chacune lançant l'erreur suivante (si les images sont mises en cache à partir d'une version antérieure, elles se chargent sans problème) :

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

ce sont les autres versions dans le 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

Changer gunicorn en 19.7.1 semble résoudre le problème; il persiste avec 19.8.0.
Comme pour le problème similaire de 2012, ce n'est pas un problème de délai d'expiration de la demande car l'erreur qu'il génère est assez immédiate. Le retour à 19.7.1 l'a corrigé, donc pour l'instant je m'en tiendrai à cela, mais ce serait bien d'utiliser la dernière version. On dirait que cela pourrait être un problème spécifique à Heroku ; Je n'ai remarqué que le mois dernier, mais je ne trouve aucune information sur le moment où ils ont changé de version.

Commentaire le plus utile

Je me suis battu avec ce même problème aujourd'hui, toute la journée. Et je _pense_ que j'ai finalement corrigé le problème. J'utilise nginx, Flask, gunicorn avec eventlet et docker.

Ma sortie (pertinente) pip freeze :

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

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

Le premier symptôme était de gros chargements de fichiers statiques lançant ERR_CONTENT_LENGTH_MISMATCH dans le navigateur. De toute évidence, cela a cassé l'application, car les grandes bibliothèques JS statiques n'étaient pas chargées.

Le deuxième symptôme était que nginx enregistrait ce qui suit dans error.log : upstream prematurely closed connection while reading upstream

Enfin, je l'ai retracé jusqu'à un élément de journal 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

Ma solution finale était de démarrer gunicorn avec le drapeau --no-sendfile , et le problème a disparu. Pourquoi? Pas sûr... Je suis juste content que ça marche.

Il convient également de mentionner que lors de mon dépannage, j'ai fait de mon mieux pour que mon nginx.conf ressemble à l'exemple trouvé ici : http://docs.gunicorn.org/en/stable/deploy.html

Tous les 14 commentaires

Je me suis battu avec ce même problème aujourd'hui, toute la journée. Et je _pense_ que j'ai finalement corrigé le problème. J'utilise nginx, Flask, gunicorn avec eventlet et docker.

Ma sortie (pertinente) pip freeze :

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

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

Le premier symptôme était de gros chargements de fichiers statiques lançant ERR_CONTENT_LENGTH_MISMATCH dans le navigateur. De toute évidence, cela a cassé l'application, car les grandes bibliothèques JS statiques n'étaient pas chargées.

Le deuxième symptôme était que nginx enregistrait ce qui suit dans error.log : upstream prematurely closed connection while reading upstream

Enfin, je l'ai retracé jusqu'à un élément de journal 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

Ma solution finale était de démarrer gunicorn avec le drapeau --no-sendfile , et le problème a disparu. Pourquoi? Pas sûr... Je suis juste content que ça marche.

Il convient également de mentionner que lors de mon dépannage, j'ai fait de mon mieux pour que mon nginx.conf ressemble à l'exemple trouvé ici : http://docs.gunicorn.org/en/stable/deploy.html

Je rencontre aussi ce problème, 19.7.0 fonctionne bien

Cela se produit-il immédiatement ou après l'envoi partiel d'une longue réponse ?

Peut être la cause d'un fichier statique

Une mise à jour pour ceci? Je suis confronté au même problème dans 19.9.0

Tout fonctionnait bien et tout d'un coup ça a commencé à arriver.

@tilgovi faites-moi savoir si vous avez besoin d'informations à ce sujet. Tout d'un coup, ce problème a commencé à apparaître

Pour moi, le problème était dû au travailleur eventlet. J'ai supprimé eventlet et tout va bien maintenant.

Je rencontre le même problème. Et la suggestion de @SaintSimmo fonctionne bien pour moi. Ce problème se produit immédiatement lors du démarrage du téléchargement d'un fichier volumineux. J'utilise flask et eventlet. Et le travail de téléchargement est effectué par send_from_directory de Flask.
Le gunicorn est démarré dans la commande suivante :
gunicorn --worker-class eventlet -w 1 -b 0.0.0.0:4000 upload:app
qui donnera l'erreur.
si "--no-sendfile" est ajouté dans la commande, aucun message d'erreur n'est envoyé. Si le travail de téléchargement peut être effectué sans "sendfile", alors quand ce "sendfile" doit-il être utilisé ?

gunicorn (version 19.9.0) même problème avec eventlet

Le 19.9.0, la recommandation de @SaintSimmo de définir --no-sendfile a également fonctionné pour moi.

Oui, le même problème et après avoir supprimé le travailleur eventlet, cela fonctionne bien.

Lorsque je démarre le serveur avec cette commande (gunicorn -w 1 -k eventlet -b 127.0.0.1:5000 wsgi:app), je reçois les exceptions ci-dessous et mon image est tronquée sur la réponse du client.
[ERROR] Erreur de socket lors du traitement de la demande.
...
BlockingIOError : [Errno 11] Ressource temporairement indisponible

En supprimant la définition de la classe de travail, cela fonctionne.
gunicorn -w 1 -b 127.0.0.1:5000 wsgi:app

@jacebrowning et @SaintSimmo , je confirme que le paramètre supplémentaire --no-sendfile dans la commande gunicorn est efficace.

Cela est généralement dû au fait que le nproc est trop peu nombreux, vous pouvez augmenter le nombre de nproc pour l'utilisateur qui exécute ce programme en éditant le fichier ' /etc/security/limits.conf '.

Souffrez-vous de ce problème ? Si vous utilisez Python 3.4 ou supérieur, mettez à jour votre version de Gunicorn.

J'ai eu le même problème avec --worker-class. J'ai mis à jour gunicorn vers 20.0.4 et le problème a été résolu.

Changer la classe ouvrière en gevent a fonctionné pour moi. --worker-class gevent

Cette page vous a été utile?
0 / 5 - 0 notes