nginx kończy połączenie po 65 000 bajtów

11

Mam nginx skonfigurowany jako interfejs aplikacji Python działającej pod gunicorn, ale nginx przerywa połączenia po wysłaniu około 65 000 danych.

Na przykład mam widok, który wygląda następująco:

def debug_big_file(request):
    return HttpResponse("x" * 500000)

Ale kiedy uzyskuję dostęp do tego adresu URL przez nginx, otrzymuję tylko 65283 bajtów:

$ curl https://example.com/debug/big-file | wc
…
curl: (18) transfer closed with outstanding read data remaining
   0       1   65283

Pamiętaj, że wszystko działa zgodnie z oczekiwaniami przy bezpośrednim dostępie do gunicorn:

$ curl http://localhost:1234/debug/big-file | wc
…
   0       1   500000

Odpowiednia konfiguracja nginx:

location / {
    proxy_pass http://localhost:1234/;
    proxy_redirect off;
    proxy_headers_hash_bucket_size 96;
}

I wersja 1.7.0 Nginx

Kilka innych faktów:

  • Liczba bajtów jest spójna od żądania do żądania, ale różni się w zależności od zawartości (po raz pierwszy zauważyłem duży plik PNG, który został odcięty po 65 372 bajtach, a nie 65 283)
  • "x" * 110000110 000 bajtów jest wysyłanych poprawnie (tzn. Zwraca wszystkie 110 000 bajtów), ale 120 000 bajtów nie
  • tcpdump sugeruje, że nginx wysyła pakiet RST do gunicorn: nginx wysyła RST
David Wolever
źródło
Przydałoby się zobaczyć (a) jak gunicorn wybiera ramki do odpowiedzi od 110k do 120k bajtów, oraz (b) jak nginx wybiera następnie kadrowanie dla tego samego zakresu wielkości ładunków próbki między 110k a 120k bajtów. Trzy sposoby ramkowania danych przez HTTP: zapewnienie długości treści; zrobić kodowanie fragmentaryczne; lub nie dawaj żadnego obramowania, z wyjątkiem obietnicy zamknięcia gniazda po ukończeniu budowy.
Brandon Rhodes
Podawany jest nagłówek o długości treści. Pozwól mi zrzucić pakiet, aby zobaczyć, co się dzieje między tymi dwoma, w przeciwnym razie…
David Wolever
Hm, bardzo dziwne. tcpdump sugeruje, że nginx aktywnie RST przetwarza połączenie (patrz edycja). nginx używa również HTTP / 1.0 i Connection: close. Potwierdziłem również, że Content-Lengthnagłówek jest poprawny.
David Wolever

Odpowiedzi:

10

W porządku! Po podwójnym sprawdzeniu dzienników nginx okazało się, że jest to problem:

2014/05/26 16:50:56 [crit] 31396#0: *11 open() "…/proxy_temp/2/00/0000000002" failed (13: Permission denied) while reading upstream, client: 1.2.3.4, server: _, request: "GET /debug/big-file HTTP/1.1", upstream: "http://127.0.0.1:1234/debug/big-file", host: "example.com"

Trochę pomylono uprawnienia do proxy_tempkatalogu, co uniemożliwiło nginx prawidłowe buforowanie do niego.

David Wolever
źródło
1
Tak, właśnie rozwiązałem taki problem, przejrzałem dzienniki nginx, miałem linię zawierającą [crit] 6636#0: *16817 open() "/var/lib/nginx/proxy/7/03/0000000037" failed (13: Permission denied) while reading upstream, zrobiłem sudo chown -R www-data:www-data /var/lib/nginx/i naprawiłem.
Epigene,