nginx mengakhiri koneksi setelah 65k byte

11

Saya punya nginx yang dikonfigurasikan sebagai front-end ke aplikasi Python yang berjalan di bawah gunicorn, tetapi nginx memutuskan koneksi setelah sekitar 65 ribu data telah dikirim.

Misalnya, saya punya tampilan yang terlihat seperti ini:

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

Tetapi ketika saya mengakses URL itu melalui nginx, saya hanya mendapatkan 65283 byte:

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

Perhatikan bahwa semuanya berfungsi seperti yang diharapkan ketika mengakses gunicorn langsung:

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

Konfigurasi nginx yang relevan:

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

Dan nginx versi 1.7.0

Beberapa fakta lain:

  • Jumlah byte konsisten dari permintaan untuk meminta, tetapi bervariasi berdasarkan konten (saya pertama kali melihatnya dengan file PNG besar, yang terputus setelah 65.372 byte, bukan 65.283)
  • 110k byte dikirim dengan benar (yaitu, "x" * 110000mengembalikan semua 110.000 byte), tetapi 120k byte tidak
  • tcpdump menunjukkan bahwa nginx mengirim paket RST ke gunicorn: nginx mengirim RST
David Wolever
sumber
Akan sangat membantu untuk melihat (a) bagaimana gunicorn memilih untuk membingkai balasan dari ukuran 110k hingga 120k byte, dan (b) bagaimana nginx kemudian memilih framing untuk rentang ukuran muatan sampel yang sama antara 110k dan 120k byte. Tiga cara HTTP dapat membingkai data: menyediakan panjang konten; lakukan pengkodean chunked; atau tidak memberikan framing sama sekali kecuali berjanji untuk menutup soket ketika tubuh sudah selesai.
Brandon Rhodes
Header panjang konten disediakan. Biarkan saya paket dump untuk melihat apa yang terjadi di antara keduanya kalau tidak ...
David Wolever
Hrm, sangat aneh. tcpdump menyarankan bahwa nginx aktif RST-ing koneksi (lihat edit). nginx juga menggunakan HTTP / 1.0 dan Connection: close. Saya juga sudah mengkonfirmasi bahwa Content-Lengthtajuknya benar.
David Wolever

Jawaban:

10

Baik! Setelah memeriksa log nginx, ini menjadi masalah:

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"

Entah bagaimana izin untuk proxy_tempdirektori menjadi kacau yang mencegah nginx melakukan buffering dengan benar.

David Wolever
sumber
1
Ya, saya baru saja memecahkan masalah seperti ini, melihat log nginx, memiliki baris yang berisi [crit] 6636#0: *16817 open() "/var/lib/nginx/proxy/7/03/0000000037" failed (13: Permission denied) while reading upstream, lakukan sudo chown -R www-data:www-data /var/lib/nginx/dan diperbaiki.
Epigene