Gunicorn: OSError: [Errno 9] Fehlerhafter Dateideskriptor

Erstellt am 10. Sept. 2018  ·  19Kommentare  ·  Quelle: benoitc/gunicorn

Ich habe dieses Problem im Raspbian-Image

[2018-09-10 20:40:11 +080] [21421] [KRITISCH] WORKER TIMEOUT (pid:21699)
[2018-09-10 20:40:11 +080] [21699] [ERROR] Socket-Fehler bei Verarbeitungsanfrage.
Traceback (letzter Anruf zuletzt):
Datei "/usr/lib/python3/dist-packages/gunicorn/workers/async.py", Zeile 62, im Handle
six.reraise(*sys.exc_info())
Datei "/usr/lib/python3/dist-packages/gunicorn/six.py", Zeile 625, in Reraise
Wert steigern
Datei "/usr/lib/python3/dist-packages/gunicorn/workers/async.py", Zeile 35, im Handle
listener_name = listener.getsockname()
OSError: [Errno 9] Fehlerhafter Dateideskriptor

Feedback Requested Investigation

Hilfreichster Kommentar

  1. Ich kann diesen Protokollfehler mit einem Setup mit nur gunicorn und uvicorn reproduzieren. Diese Fehlermeldung beginnt mit uvicorn==0.11.4 und nicht mit der vorherigen Version 0.11.3 (sowohl unter OSx als auch in einem Linux-Container). Dies stimmt mit den obigen Berichten über uvicorn überein, wo die gemeldeten Versionen immer größer als 0.11.4 . Beweise am Ende
  2. Die commit verantwortlich für diesen Fehler ist dies ein . Das Problem liegt in diesen wenigen Zeilen des gerade erwähnten Commits. Der Commit ändert nur die Reihenfolge von zwei Codeblöcken. Wenn ich diese Änderung der Reihenfolge rückgängig mache, verschwindet der Protokollfehler, während die Testsuite von uvicorn
  3. derselbe Protokollfehler tritt auf, wenn einer von beiden: starlette und fastapi oben auf dem Stapel gunicorn+uvicorn wie oben beschrieben; - führt die neueste uvicorn-Version 12.X anstelle von 0.11.4 ; - läuft gunicorn mit mehr als nur einem uvicorn Arbeiter

Beweise . Führen Sie in einem neuen Ordner auf OSX das angehängte Skript test.sh (unter OSX getestet). Zum Testen im Linux-Container speichern Sie sowohl das Skript als auch das Dockerfile und lesen dann den Header des Dockerfiles. Ich hänge auch das Log des Skripts an.

@benoitc , was halten Sie von diesem Commit in uvicorn , das den Fehler einzuführen scheint? Das Problem scheint an der Schnittstelle zwischen gunicorn und uvicorn . Können Sie die Reihenfolge der 2 Codeblöcke, die in dem oben erwähnten Commit in uvicorn geändert wurden, kommentieren? Dies kann helfen herauszufinden, warum dies auch bei den anderen Fällen der Fall ist. Bisher wurde dies auch mit aiohttp , gevent , Flask-SocketIO sanic gemeldet. Zur Vereinfachung füge ich auch das Protokoll des Skripts bei.

log_test.log

Datei _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

Datei _Dockerfile_

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

Alle 19 Kommentare

@leond08 Danke für das Ticket!

Um zu verstehen, wie es passiert, können Sie ein wenig mehr Informationen geben?

  • Welche Version von Gunicorn testest du?
  • Welchen Arbeiter verwendest du?
  • wann passiert das?

Ich verwende die neueste Version von gunicorn3
Ich verwende dafür eventlet und gevent
Ich führe meine Flask-Anwendung aus - Flask-SocketIO

Ich starte meine Hintergrundaufgabe, nachdem ein Benutzer auf die Schaltfläche geklickt hat
Meine Hintergrundaufgabenfunktion besteht darin, ein Ereignis abzuhören,
Nach dem Klicken auf die Schaltfläche "FERTIG" muss die Hintergrundaufgabe beendet werden
Senden Sie dann eine Emit-Nachricht an alle Benutzer

Hatte das gleiche Problem mit aiohttp + gunicorn, beobachte jedes Mal dieselbe Meldung, wenn Strg + c.

[INFO] Fehler beim Schließen des Sockets [Errno 9] Fehlerhafter Dateideskriptor

Ich reproduziere es nicht. Ich vermute, dass Ihre Anwendung einige fds schließt, die das oben genannte Problem verursachen.

Wir haben das gleiche Problem, es passiert nur bei 1 von 8 Containern, die im Docker-Schwarm ausgeführt werden.

Wir haben das gleiche Problem mit 1 von 9 Containern erlebt, es sieht so aus, als ob es mit Docker und Python3 und Gevent zusammenhängt.

gunicorn 20.0.4 + aiohttp 3.6.2

Gunicorn läuft als Dev-Server:

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

Fast jedes Strg+C endet mit

^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

Es spielt keine Rolle, ob die Anwendung eine Anfrage bearbeitet hat oder nicht.

Mit 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

Gleiches hier mit Gunicorn 20.0.4 + Uvicorn 0.11.5 Arbeiterklasse auf jedem Strg+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

ein Anwendungsbeispiel? Und von welcher Python-Version sprechen wir?

Ubuntu 20.04, vom System bereitgestelltes Python 3.8.2 in virtualenv

Anwendungsbeispiel: https://github.com/zgoda/newsloop-server/tree/d603a1c10c9e8be3d998f62ccc55dd73f4677115 (mit aiohttp) oder https://github.com/zgoda/newsloop-server/tree/b2a8a7f09fa9848d684b51a3 (mit aiohttp). Genaue Gunicorn-Aufrufung in meinem früheren Kommentar.

Unterschiede in der Ausgabe zwischen aiohttp und Sanic lassen mich vermuten, dass mit den Arbeitern etwas nicht stimmt.

Gleiches Problem, Python 3.8.0
sanic 19.12.2
Gunicorn 20.0.4

Bearbeiten: Dies passiert, wenn ich lokal auf meinem Mac ausführe, aber nicht, wenn ich in einem Linux-Docker laufe, könnte Ihnen helfen

Hallo,
Ich denke, dieses Problem https://github.com/benoitc/gunicorn/issues/2064 hat die gleichen Gründe.
Wir haben fast die gleichen Fehler wie in der Ausgabe, aber wir verwenden Gunicorn - 19.9.0

Ich erlebe das auch, FastAPI + die neuesten Gunicorn- und uvicorn-Worker mit Python 3.8.5

Sobald ich aufhöre, uvicorn zu verwenden (dh diese Zeile aus meiner gunicorn-Konfiguration entfernen):

worker_class = "uvicorn.workers.UvicornWorker"

Die Fehler verschwinden.

Wie oben beschrieben passiert dies, wenn Gunicorn mit Strg+C gestoppt wird oder ein anmutiges Kill-Signal an den PID gesendet wird.

[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

Hier ist eine genaue Nachbildung des Problems:

[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

Und hier ist die Ausgabe von 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

Ich habe versucht, uvicorn und gunicorn von GitHub (Master-Zweig) zu installieren, um sicherzustellen, dass ich die neuesten Fixes habe, aber das Problem blieb bestehen.

Hoffe das hilft
Fotis

  1. Ich kann diesen Protokollfehler mit einem Setup mit nur gunicorn und uvicorn reproduzieren. Diese Fehlermeldung beginnt mit uvicorn==0.11.4 und nicht mit der vorherigen Version 0.11.3 (sowohl unter OSx als auch in einem Linux-Container). Dies stimmt mit den obigen Berichten über uvicorn überein, wo die gemeldeten Versionen immer größer als 0.11.4 . Beweise am Ende
  2. Die commit verantwortlich für diesen Fehler ist dies ein . Das Problem liegt in diesen wenigen Zeilen des gerade erwähnten Commits. Der Commit ändert nur die Reihenfolge von zwei Codeblöcken. Wenn ich diese Änderung der Reihenfolge rückgängig mache, verschwindet der Protokollfehler, während die Testsuite von uvicorn
  3. derselbe Protokollfehler tritt auf, wenn einer von beiden: starlette und fastapi oben auf dem Stapel gunicorn+uvicorn wie oben beschrieben; - führt die neueste uvicorn-Version 12.X anstelle von 0.11.4 ; - läuft gunicorn mit mehr als nur einem uvicorn Arbeiter

Beweise . Führen Sie in einem neuen Ordner auf OSX das angehängte Skript test.sh (unter OSX getestet). Zum Testen im Linux-Container speichern Sie sowohl das Skript als auch das Dockerfile und lesen dann den Header des Dockerfiles. Ich hänge auch das Log des Skripts an.

@benoitc , was halten Sie von diesem Commit in uvicorn , das den Fehler einzuführen scheint? Das Problem scheint an der Schnittstelle zwischen gunicorn und uvicorn . Können Sie die Reihenfolge der 2 Codeblöcke, die in dem oben erwähnten Commit in uvicorn geändert wurden, kommentieren? Dies kann helfen herauszufinden, warum dies auch bei den anderen Fällen der Fall ist. Bisher wurde dies auch mit aiohttp , gevent , Flask-SocketIO sanic gemeldet. Zur Vereinfachung füge ich auch das Protokoll des Skripts bei.

log_test.log

Datei _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

Datei _Dockerfile_

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

Ich hatte genau das gleiche Problem. Hier ist mein Fall.

Kurz: Ich versuche, eine Testanwendung für Django dwebsocket mit gunicorn einzurichten. Wenn ich versuche, websocket_client zu verwenden, um das Ergebnis zu testen, tritt dieser Fehler jedes Mal nach dem Schließen des Websockets auf.

Umfeld :
Docker-Image: Python: 3.7
Python-Version: python3.7.6
gunicorn : version = 20.0.4, work = gevent
Django-Version: Django==2.2
dwebsocket-Version: 0.5.12

Code:

view.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')

urls.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')

Befehl zum Ausführen des Gunicorn-Servers

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

Fehlerausgabe

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 Der von Ihnen gepostete Stack-Trace sagt uns, dass dieses spezielle Socket-Objekt explizit auf Python-Ebene geschlossen wurde (dann verwendet gevent seine _dummy , um dieselben Ausnahmen zu generieren wie das Betriebssystem). Dies bedeutet, dass ein Teil Ihres Anwendungsstapels den Socket schließt, bevor die Antwort zurückgegeben wird, damit gunicorn es verarbeiten kann. Zum Zeitpunkt des Auftretens des Fehlers hatte Gunicorn noch nicht einmal HTTP-Antwort-Header gesendet.

In meinem Fall das gleiche Problem, mit dem Unterschied, dass dieser Fehler auftritt, ohne etwas zu tun. Manchmal nach 5min, manchmal nach 2h...

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen