Gunicorn: OSError : [Errno 9] Descripteur de fichier incorrect

Créé le 10 sept. 2018  ·  19Commentaires  ·  Source: benoitc/gunicorn

J'ai ce problème dans l'image raspbian

[2018-09-10 20:40:11 +0800] [21421] [CRITICAL] TEMPS D'ATTENTE DU TRAVAILLEUR (pid:21699)
[2018-09-10 20:40:11 +0800] [21699] [ERREUR] Demande de traitement d'erreur de socket.
Traceback (appel le plus récent en dernier) :
Fichier "/usr/lib/python3/dist-packages/gunicorn/workers/async.py", ligne 62, dans le handle
six.reraise(*sys.exc_info())
Fichier "/usr/lib/python3/dist-packages/gunicorn/six.py", ligne 625, en raise
augmenter la valeur
Fichier "/usr/lib/python3/dist-packages/gunicorn/workers/async.py", ligne 35, dans le handle
listener_name = listener.getsockname()
OSError : [Errno 9] Descripteur de fichier incorrect

Feedback Requested Investigation

Commentaire le plus utile

  1. Je suis capable de reproduire cette erreur de journal avec une configuration avec seulement gunicorn et uvicorn . Ce message d'erreur commence à se produire avec uvicorn==0.11.4 et non la version précédente 0.11.3 (à la fois sur OSx et dans un conteneur Linux). Ceci est cohérent avec les rapports ci-dessus avec uvicor, où les versions rapportées sont toujours supérieures à 0.11.4 . Preuve à la fin
  2. Le commit responsable de cette erreur est celui- ci . Le problème réside dans ces quelques lignes du commit que l'on vient de mentionner. Le commit ne change que l'ordre de deux blocs de code. Si j'annule ce changement d'ordre, l'erreur de journal disparaît, tout en réussissant la suite de tests de uvicorn
  3. la même erreur de journal se produit si l'un d'entre eux : utilise starlette et fastapi au-dessus de la pile gunicorn+uvicorn comme indiqué ci-dessus ; - exécute la dernière version d'uvicorn 12.X au lieu de 0.11.4 ; - exécute gunicorn avec plus d'un uvicorn worker

Preuve . Dans un nouveau dossier sur osx, exécutez le script joint test.sh (testé sur osx). Pour tester dans le conteneur Linux, enregistrez à la fois le script et le Dockerfile, puis lisez l'en-tête du Dockerfile. Je joins également le log du script.

@benoitc , que pensez-vous de ce commit dans uvicorn qui semble introduire le bug ? Le problème semble être à l'interface entre gunicorn et uvicorn . Pouvez-vous commenter l'ordre des 2 blocs de code modifiés dans le commit mentionné ci-dessus en uvicorn ? Cela peut aider à découvrir pourquoi cela se produit également dans les autres cas. Jusqu'à présent, cela a également été signalé avec aiohttp , gevent , Flask-SocketIO sanic . Je joins également le journal du script pour plus de facilité.

log_test.log

fichier _test.sh_

#!/bin/bash
python3 -m venv venv
source venv/bin/activate
pip install gunicorn==20.0.04 uvicorn==0.11.4
# create simple uvicorn app
printf "async def app(scope, receive, send):\n    await send()\n" > example.py
# spin up gunicorn with 1 uvicorn worker, and then send TERM signal to gunicorn
gunicorn example:app -w 1 -k uvicorn.workers.UvicornWorker &
sleep 5 && pkill -f gunicorn
sleep 1
# you will see 1 log entry like this one:
# [XX] [YY] [INFO] Error while closing socket [Errno 9] Bad file descriptor

printf "\n\n[INFO] if you instead bump down uvicorn's version from 11.4 to 11.3 [Errno 9] goes away:\n\n"
pip install uvicorn==0.11.3
gunicorn example:app -w 1 -k uvicorn.workers.UvicornWorker &
sleep 5 && pkill -f gunicorn

fichier _Dockerfile_

# run with:
# docker run -it $(docker build -q .)
FROM python:3.8
COPY test.sh .
RUN chmod +x /test.sh
CMD /test.sh

Tous les 19 commentaires

@leond08 Merci pour le billet !

Afin de comprendre comment cela se passe, pouvez-vous fournir un peu plus d'informations ?

  • quelle version de Gunicorn testez-vous
  • quel travailleur utilisez-vous
  • quand cela arrive-t-il ?

J'utilise la dernière version de gunicorn3
J'utilise eventlet et gevent pour cela
j'exécute mon application flask - Flask-SocketIO

Je démarre ma tâche en arrière-plan après qu'un utilisateur a cliqué sur le bouton
Ma fonction de tâche en arrière-plan est d'écouter un événement,
après avoir cliqué sur le bouton « DONE », la tâche en arrière-plan doit s'arrêter
puis envoyer un message d'émission à tous les utilisateurs

J'ai eu le même problème avec aiohttp + gunicorn, observez le même message à chaque fois lorsque ctrl + c.

[INFO] Erreur lors de la fermeture du socket [Errno 9] Descripteur de fichier incorrect

Je ne le reproduis pas. Je soupçonne que votre application ferme certains fds qui créent le problème ci-dessus.

Nous rencontrons le même problème, la seule chose est que cela ne se produit que sur 1 conteneur sur 8 exécuté dans Docker Swarm.

Nous avons rencontré le même problème avec 1 conteneur sur 9, il semble lié à docker et python3 et gevent.

gunicorn 20.0.4 + aiohttp 3.6.2

Gunicorn s'exécute en tant que serveur de développement :

gunicorn --reload app:make_app --bind localhost:5000 --worker-class aiohttp.GunicornWebWorker --workers 2 --access-logfile -

Presque tous les Ctrl+C se terminent par

^C[2020-05-23 21:49:50 +0200] [38524] [INFO] Handling signal: int
Exception ignored when trying to write to the signal wakeup fd:
Exception ignored when trying to write to the signal wakeup fd:
Traceback (most recent call last):
  File "/usr/lib/python3.8/asyncio/unix_events.py", line 42, in _sighandler_noop
Traceback (most recent call last):
  File "/usr/lib/python3.8/asyncio/unix_events.py", line 42, in _sighandler_noop
    def _sighandler_noop(signum, frame):
    def _sighandler_noop(signum, frame):
OSError: [Errno 9] Bad file descriptor
OSError: [Errno 9] Bad file descriptor
[2020-05-23 21:49:50 +0200] [38526] [INFO] Worker exiting (pid: 38526)
[2020-05-23 21:49:50 +0200] [38528] [INFO] Worker exiting (pid: 38528)
[2020-05-23 21:49:50 +0200] [38524] [INFO] Shutting down: Master

Peu importe si l'application a traité une demande ou non.

Avec Sanic 20.3.0 :

^C[2020-05-26 13:24:55 +0200] [27706] [INFO] Handling signal: int
[2020-05-26 13:24:55 +0200] [27769] [INFO] Stopping server: 27769, connections: 0
[2020-05-26 13:24:55 +0200] [27769] [INFO] Error while closing socket [Errno 9] Bad file descriptor
[2020-05-26 13:24:55 +0200] [27769] [INFO] Worker exiting (pid: 27769)
[2020-05-26 13:24:55 +0200] [27771] [INFO] Stopping server: 27771, connections: 0
[2020-05-26 13:24:55 +0200] [27771] [INFO] Error while closing socket [Errno 9] Bad file descriptor
[2020-05-26 13:24:55 +0200] [27771] [INFO] Worker exiting (pid: 27771)
[2020-05-26 13:24:55 +0200] [27706] [INFO] Shutting down: Master

Idem ici avec la classe d'ouvriers Gunicorn 20.0.4 + Uvicorn 0.11.5 à chaque Ctrl+C

INFO:     [12621] [gunicorn.error] Handling signal: int
INFO:     [12635] [gunicorn.error] Error while closing socket [Errno 9] Bad file descriptor
INFO:     [12634] [gunicorn.error] Error while closing socket [Errno 9] Bad file descriptor
INFO:     [12635] [gunicorn.error] Worker exiting (pid: 12635)
INFO:     [12634] [gunicorn.error] Worker exiting (pid: 12634)
INFO:     [12621] [gunicorn.error] Shutting down: Master

un exemple d'application ? De quelle version de Python parlons-nous également ?

Ubuntu 20.04, système fourni Python 3.8.2 dans virtualenv

Exemple d'application : https://github.com/zgoda/newsloop-server/tree/d603a1c10c9e8be3d998f62ccc55dd73f4677115 (avec aiohttp) ou https://github.com/zgoda/newsloop-server/tree/b2a8a7f San 983e (avec aiohttp) Invocation exacte de gunicorn dans mon commentaire précédent.

Les différences de sortie entre aiohttp et Sanic me font soupçonner qu'il y a quelque chose qui ne va pas chez les travailleurs.

Même problème, python 3.8.0
sanique 19.12.2
gunicorne 20.0.4

Edit : cela se produit lorsque je cours localement sur mon Mac, mais pas lorsque je fonctionne dans un docker Linux, cela pourrait vous aider

Bonjour,
Je suppose que ce problème https://github.com/benoitc/gunicorn/issues/2064 a les mêmes raisons.
Nous avons presque les mêmes erreurs que dans le problème, mais nous utilisons gunicorn - 19.9.0

Je vis cela aussi, FastAPI + les derniers travailleurs Gunicorn et uvicorn avec Python 3.8.5

Dès que j'arrête d'utiliser uvicor (c'est-à-dire supprimer cette ligne de ma configuration gunicorn):

worker_class = "uvicorn.workers.UvicornWorker"

Les erreurs disparaissent.

Comme décrit ci-dessus, cela se produit lors de l'arrêt de Gunicorn avec Ctrl+C ou de l'envoi d'un signal d'arrêt gracieux au PID.

[2020-09-12 11:56:37 +1000] [100390] [INFO] Starting gunicorn 20.0.4
[2020-09-12 11:56:37 +1000] [100390] [INFO] Listening at: http://0.0.0.0:6000 (100390)
[2020-09-12 11:56:37 +1000] [100390] [INFO] Using worker: uvicorn.workers.UvicornWorker
[2020-09-12 11:56:37 +1000] [100392] [INFO] Booting worker with pid: 100392
[2020-09-12 11:56:38 +1000] [100392] [INFO] Started server process [100392]
[2020-09-12 11:56:38 +1000] [100392] [INFO] Waiting for application startup.
[2020-09-12 11:56:38 +1000] [100392] [INFO] Application startup complete.
[2020-09-12 11:56:48 +1000] [100390] [INFO] Handling signal: term
[2020-09-12 11:56:48 +1000] [100392] [INFO] Shutting down
[2020-09-12 11:56:48 +1000] [100392] [INFO] Error while closing socket [Errno 9] Bad file descriptor
[2020-09-12 11:56:48 +1000] [100392] [INFO] Waiting for application shutdown.
[2020-09-12 11:56:48 +1000] [100392] [INFO] Application shutdown complete.
[2020-09-12 11:56:48 +1000] [100392] [INFO] Finished server process [100392]
[2020-09-12 11:56:48 +1000] [100392] [INFO] Worker exiting (pid: 100392)
[2020-09-12 11:56:48 +1000] [100390] [INFO] Shutting down: Master

Voici une réplique exacte du problème :

[fots<strong i="6">@workstation</strong> testing]$ python3.8 -V
Python 3.8.5
[fots<strong i="7">@workstation</strong> testing]$ python3.8 -m venv ~/.virtualenv/testing
[fots<strong i="8">@workstation</strong> testing]$ source ~/.virtualenv/testing/bin/activate
(testing) [fots<strong i="9">@workstation</strong> testing]$ pip install fastapi gunicorn uvicorn
Collecting fastapi
  Using cached fastapi-0.61.1-py3-none-any.whl (48 kB)
Collecting gunicorn
  Using cached gunicorn-20.0.4-py2.py3-none-any.whl (77 kB)
Collecting uvicorn
  Using cached uvicorn-0.11.8-py3-none-any.whl (43 kB)
Collecting pydantic<2.0.0,>=1.0.0
  Using cached pydantic-1.6.1-cp38-cp38-manylinux2014_x86_64.whl (11.5 MB)
Collecting starlette==0.13.6
  Using cached starlette-0.13.6-py3-none-any.whl (59 kB)
Requirement already satisfied: setuptools>=3.0 in /home/fots/.virtualenv/testing/lib/python3.8/site-packages (from gunicorn) (47.1.0)
Collecting h11<0.10,>=0.8
  Using cached h11-0.9.0-py2.py3-none-any.whl (53 kB)
Collecting websockets==8.*
  Using cached websockets-8.1-cp38-cp38-manylinux2010_x86_64.whl (78 kB)
Collecting httptools==0.1.*; sys_platform != "win32" and sys_platform != "cygwin" and platform_python_implementation != "PyPy"
  Using cached httptools-0.1.1-cp38-cp38-manylinux1_x86_64.whl (227 kB)
Collecting uvloop>=0.14.0; sys_platform != "win32" and sys_platform != "cygwin" and platform_python_implementation != "PyPy"
  Using cached uvloop-0.14.0-cp38-cp38-manylinux2010_x86_64.whl (4.7 MB)
Collecting click==7.*
  Using cached click-7.1.2-py2.py3-none-any.whl (82 kB)
Installing collected packages: pydantic, starlette, fastapi, gunicorn, h11, websockets, httptools, uvloop, click, uvicorn
Successfully installed click-7.1.2 fastapi-0.61.1 gunicorn-20.0.4 h11-0.9.0 httptools-0.1.1 pydantic-1.6.1 starlette-0.13.6 uvicorn-0.11.8 uvloop-0.14.0 websockets-8.1
WARNING: You are using pip version 20.1.1; however, version 20.2.3 is available.
You should consider upgrading via the '/home/fots/.virtualenv/testing/bin/python3.8 -m pip install --upgrade pip' command.
(testing) [fots<strong i="10">@workstation</strong> testing]$ ls -l
total 4
-rw-rw-r-- 1 fots fots 117 Sep 12 12:13 main.py
(testing) [fots<strong i="11">@workstation</strong> testing]$ cat main.py
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Hello World"}
(testing) [fots<strong i="12">@workstation</strong> testing]$ gunicorn -k uvicorn.workers.UvicornWorker main:app
[2020-09-12 12:19:05 +1000] [105788] [INFO] Starting gunicorn 20.0.4
[2020-09-12 12:19:05 +1000] [105788] [INFO] Listening at: http://127.0.0.1:8000 (105788)
[2020-09-12 12:19:05 +1000] [105788] [INFO] Using worker: uvicorn.workers.UvicornWorker
[2020-09-12 12:19:05 +1000] [105790] [INFO] Booting worker with pid: 105790
[2020-09-12 12:19:05 +1000] [105790] [INFO] Started server process [105790]
[2020-09-12 12:19:05 +1000] [105790] [INFO] Waiting for application startup.
[2020-09-12 12:19:05 +1000] [105790] [INFO] Application startup complete.
^C[2020-09-12 12:19:06 +1000] [105788] [INFO] Handling signal: int
[2020-09-12 12:19:06 +1000] [105790] [INFO] Shutting down
[2020-09-12 12:19:06 +1000] [105790] [INFO] Error while closing socket [Errno 9] Bad file descriptor
[2020-09-12 12:19:06 +1000] [105790] [INFO] Waiting for application shutdown.
[2020-09-12 12:19:06 +1000] [105790] [INFO] Application shutdown complete.
[2020-09-12 12:19:06 +1000] [105790] [INFO] Finished server process [105790]
[2020-09-12 12:19:06 +1000] [105790] [INFO] Worker exiting (pid: 105790)
[2020-09-12 12:19:07 +1000] [105788] [INFO] Shutting down: Master

Et voici la sortie pip freeze :

click==7.1.2
fastapi==0.61.1
gunicorn==20.0.4
h11==0.9.0
httptools==0.1.1
pydantic==1.6.1
starlette==0.13.6
uvicorn==0.11.8
uvloop==0.14.0
websockets==8.1

J'ai essayé d'installer uvicorn et gunicorn à partir de GitHub (branche principale) pour m'assurer d'avoir les derniers correctifs, mais le problème a persisté.

J'espère que cela t'aides
Fotis

  1. Je suis capable de reproduire cette erreur de journal avec une configuration avec seulement gunicorn et uvicorn . Ce message d'erreur commence à se produire avec uvicorn==0.11.4 et non la version précédente 0.11.3 (à la fois sur OSx et dans un conteneur Linux). Ceci est cohérent avec les rapports ci-dessus avec uvicor, où les versions rapportées sont toujours supérieures à 0.11.4 . Preuve à la fin
  2. Le commit responsable de cette erreur est celui- ci . Le problème réside dans ces quelques lignes du commit que l'on vient de mentionner. Le commit ne change que l'ordre de deux blocs de code. Si j'annule ce changement d'ordre, l'erreur de journal disparaît, tout en réussissant la suite de tests de uvicorn
  3. la même erreur de journal se produit si l'un d'entre eux : utilise starlette et fastapi au-dessus de la pile gunicorn+uvicorn comme indiqué ci-dessus ; - exécute la dernière version d'uvicorn 12.X au lieu de 0.11.4 ; - exécute gunicorn avec plus d'un uvicorn worker

Preuve . Dans un nouveau dossier sur osx, exécutez le script joint test.sh (testé sur osx). Pour tester dans le conteneur Linux, enregistrez à la fois le script et le Dockerfile, puis lisez l'en-tête du Dockerfile. Je joins également le log du script.

@benoitc , que pensez-vous de ce commit dans uvicorn qui semble introduire le bug ? Le problème semble être à l'interface entre gunicorn et uvicorn . Pouvez-vous commenter l'ordre des 2 blocs de code modifiés dans le commit mentionné ci-dessus en uvicorn ? Cela peut aider à découvrir pourquoi cela se produit également dans les autres cas. Jusqu'à présent, cela a également été signalé avec aiohttp , gevent , Flask-SocketIO sanic . Je joins également le journal du script pour plus de facilité.

log_test.log

fichier _test.sh_

#!/bin/bash
python3 -m venv venv
source venv/bin/activate
pip install gunicorn==20.0.04 uvicorn==0.11.4
# create simple uvicorn app
printf "async def app(scope, receive, send):\n    await send()\n" > example.py
# spin up gunicorn with 1 uvicorn worker, and then send TERM signal to gunicorn
gunicorn example:app -w 1 -k uvicorn.workers.UvicornWorker &
sleep 5 && pkill -f gunicorn
sleep 1
# you will see 1 log entry like this one:
# [XX] [YY] [INFO] Error while closing socket [Errno 9] Bad file descriptor

printf "\n\n[INFO] if you instead bump down uvicorn's version from 11.4 to 11.3 [Errno 9] goes away:\n\n"
pip install uvicorn==0.11.3
gunicorn example:app -w 1 -k uvicorn.workers.UvicornWorker &
sleep 5 && pkill -f gunicorn

fichier _Dockerfile_

# run with:
# docker run -it $(docker build -q .)
FROM python:3.8
COPY test.sh .
RUN chmod +x /test.sh
CMD /test.sh

J'ai eu exactement le même problème. Voici mon cas.

Bref : j'essaye d'établir une application de test pour Django dwebsocket avec gunicorn. Lorsque j'essaie d'utiliser websocket_client pour tester le résultat, après avoir fermé le websocket, cette erreur se produit à chaque fois.

Environnement :
Image Docker : python:3.7
version python : python3.7.6
gunicorn : version = 20.0.4, travail = gevent
Version Django : Django==2.2
version dwebsocket : 0.5.12

Code:

vue.py

from dwebsocket import accept_websocket

<strong i="16">@accept_websocket</strong>
def my_ws(request):
    if request.is_websocket():
        ws = request.websocket
        while True:
            msg = ws.wait(timeout=15)
            if msg is None:
                print('get None message')
                break
            else:
                msg = b'echo :' + msg
                ws.send(msg)
                print('send ws seccess')
        print('websocket close')

URL.py

from websocketInfo.views import  my_ws
from django.conf.urls import url

urlpatterns = [
    url(r'my_ws/$', my_ws, name='my_ws')
]

websocket_client

from websocket import create_connection
ws = create_connection("ws://127.0.0.1:8080/my_ws/")
print("Sending 'Hello, World'...")
ws.send("Hello, World")
print("Receiving...")
result = ws.recv()
print(result)
ws.close()
print('ws close')

commad pour exécuter le serveur gunicorn

gunicorn MyWebsocket.wsgi -b 0.0.0.0:8000 -w 3 -k gevent

sortie d'erreur

send ws seccess
get None message
websocket close
[2021-01-13 02:43:56 +0000] [101] [ERROR] Socket error processing request.
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base_async.py", line 65, in handle
    util.reraise(*sys.exc_info())
  File "/usr/local/lib/python3.7/site-packages/gunicorn/util.py", line 625, in reraise
    raise value
  File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base_async.py", line 55, in handle
    self.handle_request(listener_name, req, client, addr)
  File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/ggevent.py", line 143, in handle_request
    super().handle_request(listener_name, req, sock, addr)
  File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base_async.py", line 128, in handle_request
    util.reraise(*sys.exc_info())
  File "/usr/local/lib/python3.7/site-packages/gunicorn/util.py", line 625, in reraise
    raise value
  File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base_async.py", line 114, in handle_request
    resp.write(item)
  File "/usr/local/lib/python3.7/site-packages/gunicorn/http/wsgi.py", line 326, in write
    self.send_headers()
  File "/usr/local/lib/python3.7/site-packages/gunicorn/http/wsgi.py", line 322, in send_headers
    util.write(self.sock, util.to_bytestring(header_str, "latin-1"))
  File "/usr/local/lib/python3.7/site-packages/gunicorn/util.py", line 286, in write
    sock.sendall(data)
  File "/usr/local/lib/python3.7/site-packages/gevent/_socket3.py", line 523, in sendall
    return _socketcommon._sendall(self, data_memory, flags)
  File "/usr/local/lib/python3.7/site-packages/gevent/_socketcommon.py", line 367, in _sendall
    chunk_size = max(socket.getsockopt(SOL_SOCKET, SO_SNDBUF), 1024 * 1024)
  File "/usr/local/lib/python3.7/site-packages/gevent/_socket3.py", line 156, in __getattr__
    return getattr(self._sock, name)
  File "/usr/local/lib/python3.7/site-packages/gevent/_socket3.py", line 66, in _dummy
    raise OSError(EBADF, 'Bad file descriptor')
OSError: [Errno 9] Bad file descriptor

@ChrisXiaoShu La trace de pile que vous avez publiée nous indique que cet objet socket spécifique a été explicitement fermé au niveau Python (c'est à ce moment-là que gevent utilise ses _dummy pour générer les mêmes exceptions que le système d'exploitation). Cela signifie qu'une partie de votre pile d'applications ferme le socket avant de renvoyer la réponse pour laisser gunicorn le gérer ; au moment où l'erreur se produit, gunicorn n'avait même pas encore envoyé d'en-têtes de réponse HTTP.

Un peu le même problème dans mon cas, à la différence près que cette erreur se produit sans rien faire. Parfois après 5min, parfois après 2h...

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