104, ‚Verbindung von Peer zurückgesetzt‘ Socket-Fehler, oder wenn ein Socket Ergebnis in einem RST nicht zu schließen, anstatt FIN?

StackOverflow https://stackoverflow.com/questions/383738

Frage

Wir entwickeln einen Python-Web-Service und eine Client-Website parallel. Wenn wir eine HTTP-Anforderung vom Client an den Dienst zu machen, wirft ein Anruf konsequent eine socket.error in socket.py, in Lese:

(104, 'Connection reset by peer')

Wenn ich mit wireshark mithören, das „gute“ und „schlechte“ Antworten sehr ähnlich aussehen:

  • Aufgrund der Größe der OAuth-Header, wird die Anforderung in zwei Pakete aufgeteilt. Der Dienst reagiert auf beide mit ACK
  • Der Dienst sendet die Antwort, ein Paket pro Kopf (HTTP / 1.0 200 OK, dann ist das Datum Header, etc.). Der Client antwortet auf jede mit ACK.
  • (Good Anfrage) sendet der Server eine FIN, ACK. Der Client antwortet mit einem FIN, ACK. Der Server antwortet ACK.
  • (Bad Anfrage) Der Server sendet eine RST, ACK, der Client keine TCP-Antwort senden, die socket.error auf der Client-Seite angehoben wird.

Sowohl der Web-Service als auch der Client auf einem Gentoo Linux x86-64 Box laufen glibc-2.6.1 laufen. Wir verwenden Python 2.5.2 im gleichen virtual_env.

Der Client ist eine Django 1.0.2 App, die httplib2 0.4.0 ruft Anfragen zu machen. Wir Anfragen mit dem OAuth Signieralgorithmus Unterzeichnung mit den OAuth-Token immer auf einen leeren String gesetzt.

Der Dienst läuft Werkzeug 0.3.1, die Pythons wsgiref.simple_server verwendet. Ich lief die WSGI App durch wsgiref.validator ohne Probleme.

Es scheint, wie sollte dies zu debuggen einfach sein, aber wenn ich durch eine gute Anfrage auf der Serviceseite verfolgen, es sieht aus wie die schlechte Anfrage, in der socket._socketobject.close () Funktion, Delegatmethoden in Dummy-Drehen Methoden. Wenn die Sende- oder sendto (können sich nicht erinnern, welche) Methode abgeschaltet wird, wird die FIN oder RST gesendet, und der Client beginnt mit der Verarbeitung.

„Verbindung von Peer zurückgesetzt“ scheint Schuld auf den Dienst zu stellen, aber ich traue httplib2 entweder. Kann der Kunde schuld sein?

** Weitere Debugging - Sieht aus wie Server auf Linux **

Ich habe ein MacBook, also habe ich versucht, den Service auf ein und die Client-Website, auf der anderen ausgeführt wird. Der Linux-Client ruft den OS-X-Server ohne Fehler (FIN ACK). Das O X-Client ruft den Linux-Dienst mit dem Bug (RST ACK, und eine (54, 'Verbindung von Peer zurückgesetzt')). So sieht es aus wie es der Dienst auf Linux ist. Ist es x86_64? Eine schlechte glibc? wsgiref? Noch auf der Suche ...

** Weitere Tests - wsgiref sieht schuppig **

Wir haben die Produktion mit Apache und mod_wsgi gegangen, und die Verbindung zurückgesetzt weggegangen. Siehe meine Antwort unten, aber mein Rat ist, um die Verbindung zurückgesetzt anmelden und versuchen Sie es erneut. Dadurch wird Ihr Server lief OK im Entwicklungsmodus lassen, und fest in der Produktion.

War es hilfreich?

Lösung

Ich habe dieses Problem hatte. Siehe Der Python "Verbindung von Peer zurückgesetzt" Problem .

Sie haben (höchstwahrscheinlich) läuft afoul von kleinen Timing-Problemen auf der Grundlage des Python Globalen Interpreter Lock.

Sie können (manchmal) korrigieren dies mit einem time.sleep(0.01) strategisch platziert.

"Wo?" du fragst. Schlägt mich. Die Idee ist, etwas besser Faden Parallelität in und um die Client-Anfragen zur Verfügung zu stellen. Versuchen Sie setzen es kurz vor dem Sie den Antrag stellen, so dass der GIL zurückgesetzt und der Python-Interpreter ist, kann alle anstehenden Themen löschen.

Andere Tipps

Verwenden Sie wsgiref nicht für die Produktion. Verwenden Sie Apache und mod_wsgi, oder etwas anderes.

Wir werden weiterhin diese Verbindung setzt, um zu sehen, manchmal häufig mit wsgiref (Backend vom werkzeug Testserver verwendet, und möglicherweise andere wie der Django-Test-Server). Unsere Lösung war es, die Fehler zu protokollieren, um den Anruf in einer Schleife wiederholen, und gab nach zehn Ausfällen auf. httplib2 versucht zweimal, aber wir brauchten ein paar mehr. Sie scheinen auch in Bündeln zu kommen -. Hinzufügen einer 1 Sekunde Schlaf könnte das Problem löschen

Wir haben noch nie eine Verbindung zurückgesetzt beim Laufen durch Apache und mod_wsgi gesehen. Ich weiß nicht, was sie anders machen, (vielleicht sie gerade sie maskieren), aber sie werden nicht angezeigt.

Wenn wir die lokale Entwickler-Community um Hilfe gebeten, jemand bestätigt, dass sie eine Menge Verbindung setzt mit wsgiref sehen, die auf dem Produktionsserver gehen weg. Es gibt einen Fehler gibt, aber es wird schwer sein, sie zu finden.

Ich weiß, Sie Python verwenden, aber ich fand diesen Java Artikel nützlich sein.

http: //java.sun. com / JavaSE / 6 / docs / technotes / guides / net / articles / connection_release.html

Normalerweise würde man eine RST, wenn man eine enge tun, die verweilen nicht (dh, in dem Daten durch den Stapel verworfen werden, wenn sie gesendet und ACK'd wurde nicht) und ein normales FIN, wenn Sie erlauben die Nähe zum Verweilen ein (dh der Nähe wartet auf die Daten während der Übertragung ACK'd werden).

Vielleicht alles, was Sie tun müssen, Ihre Steckdose wird zum Verweilen ein, so dass Sie die Racebedingung zwischen einem nicht Verweilen entfernen nahe an der Steckdose getan und die ACKs ankommen?

Ich hatte das gleiche Problem jedoch mit einem Upload von einer sehr großen Datei tut eine Python-Client-Anforderungen Buchung auf einen nginx + uwsgi Backend verwendet wird.

Was ist die Ursache endete als war das Backend für Uploads niedriger als eine Obergrenze für die maximale Dateigröße hatte, was der Kunde zu senden versucht.

Der Fehler zeigte nie in unserem uwsgi logs bis da diese Grenze tatsächlich ein von nginx auferlegt war.

die Grenze in nginx Upping entfernt, um den Fehler.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top