104, "Reset połączenia przez peer" błąd gniazda, lub kiedy zamknięcie gniazda powoduje RST zamiast FIN?

Równolegle rozwijamy usługę internetową Pythona i stronę klienta. Gdy wykonujemy żądanie HTTP od klienta do usługi, jedno wywołanie konsekwentnie podnosi Gniazdo.błąd w socket.py, w czytaniu:

(104, 'Connection reset by peer')

Kiedy słucham z wiresharkiem, odpowiedzi" dobre "i" złe " wyglądają bardzo podobnie:

  • ze względu na rozmiar nagłówka OAuth, żądanie jest podzielone na dwa pakiety. Serwis odpowiada zarówno za pomocą ACK
  • serwis wysyła odpowiedź, jeden pakiet na nagłówek (HTTP/1.0 200 OK, potem nagłówek daty, itd.). Klient odpowiada na każdą z nich za pomocą ACK.
  • (dobre żądanie) serwer wysyła FIN, ACK. Klient odpowiada płetwą, ACK. Serwer odpowiada ACK.
  • (Bad request) serwer wysyła RST, ACK, klient nie wysyła odpowiedzi TCP, Gniazdo.błąd pojawia się po stronie klienta.

Zarówno usługa sieciowa, jak i klient działają na Gentoo Linux x86-64 Box z glibc-2.6.1. Jesteśmy używanie Pythona 2.5.2 wewnątrz tego samego virtual_env.

Klientem jest aplikacja Django 1.0.2, która wywołuje httplib2 0.4.0, aby wysyłać żądania. Podpisujemy żądania algorytmem podpisywania OAuth, z tokenem OAuth zawsze ustawionym na pusty łańcuch.

Usługa działa z Werkzeug 0.3.1, który używa wsgiref Pythona.simple_server. Przepuściłem aplikację WSGI przez wsgiref.walidator bez problemów.

Wygląda na to, że powinno to być łatwe do debugowania, ale kiedy prześledzę dobry request po stronie serwisowej, wygląda jak złe żądanie, w gnieździe._socketobject.funkcja close (), zamieniająca metody delegatów w metody atrapy. Gdy metoda send lub sendto (nie pamiętam która) jest wyłączona, wysyłany jest FIN lub RST i klient rozpoczyna przetwarzanie.

" Reset połączenia przez peera " wydaje się obwiniać usługę, ale ja też nie ufam httplib2. Czy klient może być winny?

** dalsze debugowanie-wygląda jak serwer na Linuksie **

Mam MacBooka, więc próbowałem uruchomić usługę na jednym, a Stronę klienta na drugim. Klient Linuksa wywołuje OS X server bez błędu (FIN ACK). Klient OS X wywołuje usługę Linux z błędem (RST ACK, and a (54, 'Reset połączenia przez peera')). Wygląda na to, że to usługa działająca na Linuksie. Czy to x86_64? Zły glibc? wsgiref? Wciąż szukam...

** dalsze testy-wsgiref wygląda łuszcząco * *

Ruszyliśmy do produkcji z Apache i mod_wsgi, a resety połączenia zniknęły. Zobacz moją odpowiedź poniżej, ale radzę zalogować reset połączenia i spróbować ponownie. Pozwoli to Twojemu serwerowi działać dobrze w trybie deweloperskim i solidnie w produkcji.

Author: jwhitlock, 2008-12-20

4 answers

Mam taki problem. Zobacz Problem Pythona "Reset Połączenia Przez Peera" .

Masz (najprawdopodobniej) problem z synchronizacją w oparciu o globalną blokadę interpretera Pythona.

Możesz (czasami) to poprawić za pomocą time.sleep(0.01) umieszczonego strategicznie.

"Gdzie?"pytasz. Nie mam pojęcia. Chodzi o to, aby zapewnić lepszą współbieżność wątków w żądaniach klientów i wokół nich. Spróbuj umieścić to po prostu przed {[11] } składasz prośbę tak, aby GIL był reset i interpreter Pythona może wyczyścić wszystkie oczekujące wątki.

 25
Author: S.Lott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-01 03:05:57

Nie używaj wsgiref do produkcji. Użyj Apache i mod_wsgi lub czegoś innego.

Nadal widzimy Resetowanie tych połączeń, czasami często, za pomocą wsgiref (zaplecza używanego przez serwer testowy werkzeug i ewentualnie innych, takich jak serwer testowy Django). Naszym rozwiązaniem było zarejestrowanie błędu, ponowne próba połączenia w pętli i poddanie się po dziesięciu niepowodzeniach. httplib2 próbuje dwa razy, ale potrzebowaliśmy jeszcze kilku. Wydaje się, że są również w pęczkach - dodanie 1 sekundy snu może oczyścić problem.

Nigdy nie widzieliśmy resetowania połączenia podczas uruchamiania przez Apache i mod_wsgi. Nie wiem co robią inaczej, (może po prostu je maskują), ale się nie pojawiają.

Kiedy poprosiliśmy lokalną społeczność deweloperów o pomoc, ktoś potwierdził, że widzi wiele resetów połączeń z wsgiref, które znikają na serwerze produkcyjnym. Jest tam pluskwa, ale ciężko będzie ją znaleźć.

 11
Author: jwhitlock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-27 00:37:29

Normalnie, dostajesz RST, jeśli wykonasz zamknięcie, które nie pozostaje w tyle (tzn. w którym dane mogą być odrzucone przez stos, jeśli nie zostały wysłane i ACK 'D) i normalny FIN, jeśli pozwolisz na zamknięcie (tzn. zamknięcie czeka na ACK' d przesyłanych danych).

Być może wszystko, co musisz zrobić, to ustawić gniazdo na linger tak, że można usunąć stan wyścigu między Nie utrzymujące się blisko wykonane na gnieździe i ACKs przybywających?

 3
Author: Len Holgate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-21 12:44:18

Miałem jednak ten sam problem z przesłaniem bardzo dużego pliku za pomocą klienta Python-request do zaplecza nginx+uwsgi.

Okazało się, że przyczyną było ograniczenie maksymalnego rozmiaru pliku dla przesyłanych plików niższego niż to, co klient próbował wysłać.

W związku z tym, że nie jesteśmy w stanie znaleźć odpowiedzi na twoje pytania, nie będziemy w stanie odpowiedzieć na to pytanie. W tym celu należy skontaktować się z działem obsługi klienta.
 1
Author: David Simic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-15 23:52:03