Saya sudah mulai menggunakan Nginx sebagai proxy terbalik untuk satu set server yang menyediakan semacam layanan.
Layanan bisa agak lambat di kali (berjalan di Jawa dan JVM kadang-kadang terjebak dalam "pengumpulan sampah penuh" yang mungkin memakan waktu beberapa detik), jadi saya telah mengatur proxy_connect_timeout
ke 2 detik, yang akan memberi Nginx cukup waktu untuk mencari mengetahui bahwa layanan macet di GC dan tidak akan merespons dalam waktu, dan harus meneruskan permintaan ke server yang berbeda.
Saya juga telah mengatur proxy_read_timeout
untuk mencegah proksi terbalik macet jika layanan itu sendiri membutuhkan terlalu banyak waktu untuk menghitung respons - sekali lagi, itu harus memindahkan permintaan ke server lain yang seharusnya cukup bebas untuk mengembalikan respons tepat waktu.
Saya telah menjalankan beberapa tolok ukur dan saya dapat melihat dengan jelas bahwa beberapa proxy_connect_timeout
berfungsi dengan baik karena beberapa permintaan kembali tepat pada waktu yang ditentukan untuk waktu habis koneksi, karena layanan macet dan tidak menerima koneksi masuk (layanan menggunakan Jetty sebagai tertanam wadah servlet). Ini proxy_read_timeout
juga berfungsi, karena saya dapat melihat permintaan yang kembali setelah batas waktu yang ditentukan di sana.
Masalahnya adalah bahwa saya akan mengharapkan untuk melihat beberapa permintaan yang habis setelah itu proxy_read_timeout + proxy_connect_timeout
, atau hampir sepanjang waktu itu, jika layanan macet dan tidak akan menerima koneksi ketika Nginx mencoba mengaksesnya, tetapi sebelum Nginx dapat kehabisan waktu - itu akan dirilis dan mulai memproses, tetapi terlalu lambat dan Nginx akan dibatalkan karena batas waktu baca. Saya percaya bahwa layanan memiliki kasus seperti itu, tetapi setelah menjalankan beberapa tolok ukur, total jutaan permintaan - saya gagal melihat satu permintaan yang kembali dalam apa pun di atas proxy_read_timeout
(yang merupakan batas waktu lebih besar).
Saya akan sangat menghargai komentar tentang masalah ini, meskipun saya pikir itu bisa disebabkan oleh bug di Nginx (saya belum melihat kode, jadi ini hanya asumsi) bahwa penghitung waktu habis tidak mendapatkan reset setelah koneksi berhasil, jika Nginx tidak membaca apa pun dari server hulu.
proxy_read_timeout
bukan "batas waktu global", tetapi antara 2 operasi baca.proxy_read_timeout + proxy_connect_timeout
.Jawaban:
Saya sebenarnya tidak dapat mereproduksi ini di:
Saya mengatur ini di nginx.conf saya:
Saya kemudian menyiapkan dua server uji. Satu yang hanya akan habis pada SYN, dan yang akan menerima koneksi tetapi tidak pernah menanggapi:
Lalu saya mengirim satu koneksi tes:
Kemudian tonton error_log yang menunjukkan ini:
kemudian:
Dan kemudian access.log yang memiliki batas waktu 30-an yang diharapkan (10 + 20):
Berikut adalah format log yang saya gunakan yang mencakup batas waktu hulu individu:
sumber
proxy_send_timeout
) dan ketika Anda telah mengaturnya menjadi lebih tinggiproxy_connection_timeout
, itu sebenarnya dapat menjelaskan keterlambatan selama 20 detikproxy_read_timeout
. Ketika Anda mengatakan "meludahkan garis sangat lambat" - apa maksud Anda?proxy_read_timeout
salah satu permintaan gagal sepenuhnya atau memungkinkan sepenuhnya. Ini juga menjelaskan perbedaan antara perilaku yang Anda lihat dan perilaku yang saya lihat.Connect timeout berarti kios TCP saat berjabat tangan (misalnya, tidak ada SYN_ACKs). TCP akan mencoba mengirim ulang SYN, tetapi Anda hanya memberikan 2 detik. ke Nginx untuk pergi menggunakan Server lain, sehingga tidak punya waktu untuk mengirim kembali SYNs.
UPD. : Tidak dapat menemukan di dokumen, tetapi tcpdump menunjukkan bahwa ada 3 detik. keterlambatan antara 1 mengirim SYN dan upaya 2 untuk mengirim SYN.
sumber