NGINX: przekroczono limit czasu przesyłania danych (110: przekroczono limit czasu połączenia) podczas odczytu nagłówka odpowiedzi z nadawcy

130

Mam Puma działającą jako nadrzędny serwer aplikacji i Riak jako mój klaster bazy danych w tle. Kiedy wysyłam żądanie, które mapuje, zmniejsza porcję danych dla około 25 000 użytkowników i zwraca je z Riaka do aplikacji, pojawia się błąd w dzienniku Nginx:

Upstream przekroczył limit czasu (110: przekroczono limit czasu połączenia) podczas odczytu nagłówka odpowiedzi z nadawcy

Jeśli zapytam mojego upstream bezpośrednio bez serwera proxy Nginx, z tym samym żądaniem, otrzymam wymagane dane.

Limit czasu Nginx następuje po umieszczeniu serwera proxy.

**nginx.conf**

http {
    keepalive_timeout 10m;
    proxy_connect_timeout  600s;
    proxy_send_timeout  600s;
    proxy_read_timeout  600s;
    fastcgi_send_timeout 600s;
    fastcgi_read_timeout 600s;
    include /etc/nginx/sites-enabled/*.conf;
}

**virtual host conf**

upstream ss_api {
  server 127.0.0.1:3000 max_fails=0  fail_timeout=600;
}

server {
  listen 81;
  server_name xxxxx.com; # change to match your URL

  location / {
    # match the name of upstream directive which is defined above
    proxy_pass http://ss_api; 
    proxy_set_header  Host $http_host;
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_cache cloud;
    proxy_cache_valid  200 302  60m;
    proxy_cache_valid  404      1m;
    proxy_cache_bypass $http_authorization;
    proxy_cache_bypass http://ss_api/account/;
    add_header X-Cache-Status $upstream_cache_status;
  }
}

Nginx ma kilka dyrektyw limitu czasu. Nie wiem, czy brakuje mi czegoś ważnego. Każda pomoc byłaby bardzo mile widziana ....

user2768537
źródło
Powinien upłynąć limit czasu po 600 sekundach, prawda? Możesz to sfałszować czasowo, konfigurując serwer TCP na 127.0.0.1:3000, który po prostu akceptuje połączenia i nic z nimi nie robi, aby sprawdzić, jak długo to trwa. Powinno być 600s ...
rogerdpack

Odpowiedzi:

47

Dzieje się tak, ponieważ nadrzędny strumień zajmuje zbyt wiele czasu, aby odpowiedzieć na żądanie, a NGINX uważa, że ​​nadrzędny już nie mógł przetworzyć żądania, więc odpowiada z błędem. Po prostu dołącz i zwiększ proxy_read_timeout w locationbloku konfiguracyjnym. To samo przytrafiło się mnie i użyłem 1-godzinnego limitu czasu dla wewnętrznej aplikacji w pracy:

proxy_read_timeout 3600;

Dzięki temu NGINX będzie czekał godzinę (3600 s), aż jego serwer nadrzędny zwróci coś.

Sergio Gonzalez
źródło
6
Należy pamiętać, że mając proxy_read_timeoutw http sekcji nie może pomóc. Mam proxy_passdyrektywę w sekcji lokalizacji i tylko tam proxy_read_timeoutustawienie miało znaczenie. (nginx 1.16.0)
JonnyJD
Wydaje mi się, że działa w http / serwerze / lokalizacji dla mnie ... może coś się zmieniło :)
rogerdpack
39

Powinieneś zawsze powstrzymywać się od zwiększania limitów czasu, wątpię, czy czas odpowiedzi serwera zaplecza jest tutaj problemem w każdym przypadku.

Obejrzałem ten problem, usuwając flagę utrzymywania połączenia i określając wersję http zgodnie z odpowiedzią tutaj: https://stackoverflow.com/a/36589120/479632

server {
    location / {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host      $http_host;

        # these two lines here
        proxy_http_version 1.1;
        proxy_set_header Connection "";

        proxy_pass http://localhost:5000;
    }
}

Niestety nie mogę wyjaśnić, dlaczego to działa i nie udało mi się go rozszyfrować na podstawie dokumentów wymienionych w odpowiedzi, do której prowadzą linki, więc jeśli ktoś ma wyjaśnienie, byłbym bardzo zainteresowany, aby je usłyszeć.

Almund
źródło
1
Dlaczego nie miałbyś zmieniać wartości, proxy_read_timeoutjeśli wiesz, że serwer proxy (nawet dla określonego adresu URL) wymaga więcej czasu przetwarzania?
Josh M.
Cześć! Nie pamiętam już dokładnego problemu, ale myślę, że nie był on związany z faktycznym czasem dla adresu URL, ale raczej z tym, że limit czasu nie był poprawnie przetwarzany bez tych ustawień.
Almund
@magicbacon to było lata temu, więc ledwo pamiętam tę sprawę, ale zmieniłeś $http_hostprawo? Zgaduję, że to nie poleciałoby dla https. Mogą być wymagane dodatkowe ustawienia również do przekazywania żądań https.
Almund
+1 ... to wygląda na niezręczny hack, ale tak naprawdę pochodzi z oficjalnej dokumentacji :) nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive Mam nieco inny problem "przedwcześnie zamknięte połączenie podczas czytania odpowiedzi nagłówek z upstream ”, kiedy używam dyrektywy upstream z funkcją keepalive i użycie tych dwóch linii wydaje się to naprawić.
Karussell
1
@TimDavis Widzę, może to lepiej. Myślę, że może to zależeć od ruchu, jak w tym poście, mówiąc, że jest to wymagane dla WebSockets: serverlab.ca/tutorials/linux/web-servers-linux/ ...
Almund
26

Najpierw dowiedz się, który upstream zwalnia, sprawdzając plik dziennika błędów nginx i odpowiednio dostosuj czas odczytu w moim przypadku był to fastCGI

2017/09/27 13:34:03 [error] 16559#16559: *14381 upstream timed out (110: Connection timed out) while reading response header from upstream, client:xxxxxxxxxxxxxxxxxxxxxxxxx", upstream: "fastcgi://unix:/var/run/php/php5.6-fpm.sock", host: "xxxxxxxxxxxxxxx", referrer: "xxxxxxxxxxxxxxxxxxxx"

Więc muszę dostosować fastcgi_read_timeout w mojej konfiguracji serwera

 location ~ \.php$ {
     fastcgi_read_timeout 240;
     ...
 }

Zobacz: oryginalny post

Ruberandinda Patience
źródło
Oto sposób na dodanie informacji o czasie, gdy nie można zobaczyć, ile „potrzebujesz”, aby je zwiększyć: stackoverflow.com/questions/18627469/… FWIW
rogerdpack
10

W twoim przypadku pomaga to trochę w optymalizacji serwera proxy lub możesz użyć „# ustawień limitu czasu”

location / 
{        

  # time out settings
  proxy_connect_timeout 159s;
  proxy_send_timeout   600;
  proxy_read_timeout   600;
  proxy_buffer_size    64k;
  proxy_buffers     16 32k;
  proxy_busy_buffers_size 64k;
  proxy_temp_file_write_size 64k;
  proxy_pass_header Set-Cookie;
  proxy_redirect     off;
  proxy_hide_header  Vary;
  proxy_set_header   Accept-Encoding '';
  proxy_ignore_headers Cache-Control Expires;
  proxy_set_header   Referer $http_referer;
  proxy_set_header   Host   $host;
  proxy_set_header   Cookie $http_cookie;
  proxy_set_header   X-Real-IP  $remote_addr;
  proxy_set_header X-Forwarded-Host $host;
  proxy_set_header X-Forwarded-Server $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Dimitrios
źródło
Dla mnie ma to znaczenie, mając te ustawienia w sekcji lokalizacji . Posiadanie ich w sekcji http nie pomogło (pssibly, ponieważ miałem też proxy_passw sekcji lokalizacji .
JonnyJD
Co dokładnie optymalizujesz za pomocą tych deklaracji?
Vlad
9

Myślę, że ten błąd może wystąpić z różnych powodów, ale może być specyficzny dla modułu, którego używasz. Na przykład widziałem to używając modułu uwsgi, więc musiałem ustawić "uwsgi_read_timeout".

Richard
źródło
2
Myślę, że uwsgi_read_timeout 3600; proxy_send_timeout 3600; proxy_read_timeout 3600; pracuje dla mnie.
tyan
9

Poleciłbym przyjrzeć się error_logs, szczególnie części upstream, gdzie pokazuje konkretny upstream, który wygasa.

Następnie w oparciu o które można dostosować proxy_read_timeout, fastcgi_read_timeoutalbo uwsgi_read_timeout.

Upewnij się również, że Twoja konfiguracja została załadowana.

Więcej szczegółów tutaj Upstream upłynął limit czasu Nginx (dlaczego i jak to naprawić)

gansbrest
źródło
4

Jak wielu innych wskazało tutaj, zwiększenie ustawień limitu czasu dla NGINX może rozwiązać problem.

Jednak zwiększenie ustawień limitu czasu może nie być tak proste, jak sugeruje wiele z tych odpowiedzi. Sam napotkałem ten problem i próbowałem zmienić ustawienia limitu czasu w pliku /etc/nginx/nginx.conf , jak sugerują prawie wszyscy w tych wątkach. Ani trochę mi to nie pomogło; nie było widocznej zmiany w ustawieniach limitu czasu NGINX. Teraz, wiele godzin później, w końcu udało mi się rozwiązać ten problem.

Rozwiązanie znajduje się w tym wątku na forum i jest napisane, że powinieneś umieścić ustawienia limitu czasu w /etc/nginx/conf.d/timeout.conf (a jeśli ten plik nie istnieje, powinieneś go utworzyć). Użyłem tych samych ustawień co sugerowane w wątku:

proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
Andreas Forslöw
źródło
1

Miałem ten sam problem i okazało się, że był to „codzienny” błąd w kontrolerze szyn. Nie wiem dlaczego, ale na produkcji puma raz po raz uruchamia błąd powodując komunikat:

Upstream przekroczył limit czasu (110: przekroczono limit czasu połączenia) podczas odczytu nagłówka odpowiedzi z nadawcy

Prawdopodobnie dlatego, że Nginx nieustannie próbuje pobrać dane z pumy.

Sprawdź plik dziennika / puma.stderr.log, aby zobaczyć, czy tak jest.

aarkerio
źródło
0

Z naszej strony używał spdy z pamięcią podręczną proxy. Po wygaśnięciu pamięci podręcznej otrzymujemy ten błąd, dopóki pamięć podręczna nie zostanie zaktualizowana.

timhaak
źródło
0

Mam nadzieję, że to komuś pomoże: napotkałem ten błąd, a przyczyną było złe pozwolenie na folder dziennika dla phpfpm, po zmianie go, aby phpfpm mógł do niego pisać, wszystko było w porządku.

Maurício Otta
źródło
0

Aby uzyskać proxy_upstreamlimit czasu, wypróbowałem powyższe ustawienie, ale te nie zadziałały.

Ustawienie resolver_timeoutdziałało dla mnie, wiedząc, że wygenerowanie komunikatu o przekroczeniu limitu czasu przesyłania danych zajęło 30 sekund. Np. Me.atwibble.com nie może zostać rozwiązane (110: przekroczono limit czasu operacji) .

http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver_timeout

David Mercer
źródło