Zacząłem używać Nginx jako odwrotnego proxy dla zestawu serwerów, które świadczą jakąś usługę.
Usługa może być czasami dość powolna (działa na Javie, a JVM czasami utknie w „pełnym śmieciu”, co może potrwać kilka sekund), więc ustawiłem na proxy_connect_timeout
2 sekundy, co da Nginxowi wystarczająco dużo czasu na wymyślenie obecnie usługa utknęła na GC i nie odpowie na czas i powinna przekazać żądanie do innego serwera.
Ustawiłem również, proxy_read_timeout
aby zapobiec blokowaniu się zwrotnego serwera proxy, jeśli sama usługa zajmuje zbyt dużo czasu na obliczenie odpowiedzi - ponownie powinna przenieść żądanie na inny serwer, który powinien być wystarczająco wolny, aby zwrócić szybką odpowiedź.
Uruchomiłem kilka testów porównawczych i wyraźnie widzę, że proxy_connect_timeout
działa poprawnie, ponieważ niektóre żądania zwracają się dokładnie w czasie określonym dla limitu czasu połączenia, ponieważ usługa jest zablokowana i nie przyjmuje połączeń przychodzących (usługa używa Jetty jako wbudowanego pojemnik serwletu). proxy_read_timeout
Również działa, jak widzę, że wnioski o zwrot Po upływie czasu określonego tam.
Problem polega na tym, że spodziewałbym się, że niektóre żądania przekroczą limit czasu proxy_read_timeout + proxy_connect_timeout
lub prawie tak długo, jeśli usługa utknie i nie zaakceptuje połączeń, gdy Nginx spróbuje uzyskać do niej dostęp, ale zanim Nginx zdoła przekroczyć limit czasu - zostanie zwolniona i rozpoczyna przetwarzanie, ale jest zbyt wolny i Nginx przerwałby z powodu przekroczenia limitu czasu odczytu. Uważam, że usługa ma takie przypadki, ale po uruchomieniu kilku testów porównawczych, w sumie kilku milionów żądań - nie widziałem żadnego żądania, które zwraca coś powyżej proxy_read_timeout
(co oznacza dłuższy limit czasu).
Byłbym wdzięczny za każdy komentarz na ten temat, choć myślę, że może to wynikać z błędu w Nginx (muszę jeszcze przyjrzeć się kodowi, więc to tylko założenie), że licznik limitu czasu nie resetuje się po połączeniu powiedzie się, jeśli Nginx nie odczytał niczego z serwera nadrzędnego.
proxy_read_timeout
nie jest to „globalny limit czasu”, ale między 2 operacjami odczytu.proxy_read_timeout + proxy_connect_timeout
.Odpowiedzi:
Nie byłem w stanie odtworzyć tego na:
Skonfigurowałem to w moim pliku nginx.conf:
Następnie skonfigurowałem dwa serwery testowe. Taki, który po prostu przekroczy limit czasu w SYN i taki, który zaakceptuje połączenia, ale nigdy nie odpowie:
Następnie wysłałem jedno połączenie testowe:
Potem obejrzał error_log, który pokazał to:
następnie:
A następnie access.log, który ma spodziewany limit 30s (10 + 20):
Oto używany przeze mnie format dziennika, który obejmuje indywidualne przekroczenia limitu czasu:
źródło
proxy_send_timeout
), a ponieważ ustawiłeś go na wyższą wartośćproxy_connection_timeout
, może to faktycznie powodować opóźnienie w ciągu 20 sekundproxy_read_timeout
. Kiedy mówisz „wypluwaj wiersze naprawdę powoli” - co masz na myśli?proxy_read_timeout
albo całkowicie zawiedzie żądanie, albo całkowicie na to pozwala. To wyjaśnia także różnicę między zachowaniem, które widzisz, a zachowaniem, które widzę.Limit czasu połączenia oznacza opóźnienie TCP podczas uzgadniania (np. Nie było SYN_ACK). TCP spróbuje ponownie wysłać SYN, ale dałeś tylko 2 sekundy. do Nginx, aby przejść na inny Serwer, więc po prostu nie ma czasu na ponowne wysyłanie SYN.
UPD.: Nie można znaleźć w dokumentach, ale tcpdump pokazuje, że są 3 sekundy. opóźnienie między 1. wysłanym SYN a 2. próbą wysłania SYN.
źródło