Jak zapobiec przekroczeniu limitu czasu bramy za pomocą FastCGI na Nginx

203

Używam Django, FastCGI i Nginx. Tworzę interfejs API, w którym ktoś może wysłać dane przez XML, które przetworzę, a następnie zwrócą kody statusu dla każdego wysłanego węzła.

Problem polega na tym, że Nginx wyrzuci limit czasu bramy 504, jeśli przetworzenie kodu XML potrwa zbyt długo - myślę, że dłużej niż 60 sekund.

Chciałbym więc skonfigurować Nginx, aby jeśli jakieś żądania pasujące do lokalizacji / interfejsu API nie przekraczały limitu czasu przez 120 sekund. Jakie ustawienie to umożliwi.

Do tej pory mam:

    # Handles all api calls
    location ^~ /api/ {
        proxy_read_timeout 120;
        proxy_connect_timeout 120;
        fastcgi_pass 127.0.0.1:8080;
    }

Edycja: To, co mam, nie działa :)

płaszcze
źródło
7
Możesz ustawić wartości limitu czasu na „2m” zamiast „120”.
Cenk Alti
1
Wydaje się źle, że dane nie są przesyłane strumieniowo ... tzn. Serwer zaczyna odpowiadać w ciągu 60 sekund lub dłużej wydaje się niedopuszczalne.
Adam Gent

Odpowiedzi:

245

Przekroczono limity czasu proxy, w przypadku serwerów proxy, a nie FastCGI ...

Dyrektywy, które wpływają na limity czasu FastCGI to client_header_timeout: client_body_timeouti send_timeout.

Edycja : Biorąc pod uwagę to, co znaleziono na wiki nginx, dyrektywa send_timeout jest odpowiedzialna za ustawienie ogólnego limitu czasu odpowiedzi (co było nieco mylące). Dla FastCGI tam fastcgi_read_timeoutktóry ma wpływ na czas oczekiwania odpowiedzi FastCGI proces .

HTH.

zgoda
źródło
8
Dla każdego używającego uwsgi i mającego ten błąd, uwsgi_read_timeout 600; naprawiono mój problem.
Homer6
2
Moje pytanie brzmiałoby tutaj (jako administrator serwera), gdzie mam to zmienić? plik httpd.conf?
jeffkee
2
Jeśli to pomaga, mój był w / etc / nginx / w systemie DV Media Temple.
jeffkee
Abdo daje dobry sposób na debugowanie. Jeśli nadal masz problemy, może być konieczne zwiększenie maksymalnego rozmiaru wiadomości klienta w nginx.conf (client_max_body_size ** M;)
Sam Grondahl
2
Zwiększenie limitu czasu imho nie jest właściwym rozwiązaniem.
JazzCat
24

Dla tych, którzy używają nginx z jednorożcem i szynami, najprawdopodobniej limit czasu jest w twoim unicorn.rbpliku

umieść duży limit czasu w Unicorn.rb

timeout 500

jeśli nadal napotykasz problemy, spróbuj mieć fail_timeout = 0 w swoim górnym kanale w nginx i sprawdź, czy to rozwiąże problem. Służy to do debugowania i może być niebezpieczne w środowisku produkcyjnym.

upstream foo_server {
        server 127.0.0.1:3000 fail_timeout=0;
}
Abdo
źródło
3
Myślę, że ludzie głosowali za tym, ponieważ chodzi o Django, jednak twoja odpowiedź naprawiła problem z
przekroczeniem
4

W httpsekcji nginx (/etc/nginx/nginx.conf) dodaj lub zmodyfikuj:

keepalive_timeout 300s

W serversekcji nginx (/etc/nginx/sites-available/your-config-file.com) dodaj następujące linie:

client_max_body_size 50M;
fastcgi_buffers 8 1600k;
fastcgi_buffer_size 3200k;
fastcgi_connect_timeout 300s;
fastcgi_send_timeout 300s;
fastcgi_read_timeout 300s;

W phppliku w sprawie 127.0.0.1:9000 (/etc/php/7.X/fpm/pool.d/www.conf) zmień:

request_terminate_timeout = 300

Mam nadzieję, że ci pomogę.

Jose Carlos Ramos Carmenates
źródło
Czy zdarzy się coś „złego”, jeśli zmienię czas na 10000 sekund?
utdev
Nie dzieje się nic złego, ale twoje usługi czekają dłużej. Możesz zmienić tę wartość, jak chcesz.
Jose Carlos Ramos Carmenates
1

Jeśli używasz jednorożca.

Spójrz topna swój serwer. Unicorn prawdopodobnie używa obecnie 100% procesora. Istnieje kilka przyczyn tego problemu.

  • Powinieneś sprawdzić swoje żądania HTTP, niektóre z nich mogą być bardzo trudne.

  • Sprawdź wersję jednorożca. Być może niedawno go zaktualizowałeś i coś się zepsuło.

Pavel Kalashnikov
źródło
0

W serwerze proxy ustawia się tak

location / {

                proxy_pass http://ip:80;                

                proxy_connect_timeout   90;
                proxy_send_timeout      90;
                proxy_read_timeout      90;

            }

W serwerze php tak ustawiony

server {
        client_body_timeout 120;
        location = /index.php {

                #include fastcgi.conf; //example
                #fastcgi_pass unix:/run/php/php7.3-fpm.sock;//example veriosn

                fastcgi_read_timeout 120s;
       }
}
Kamil Dąbrowski
źródło