Apakah HTTP reverse proxy biasanya mengaktifkan HTTP Keep-Alive di sisi klien dari koneksi yang diproksi dan tidak di sisi server?

30

HAProxy memiliki kemampuan untuk mengaktifkan HTTP tetap-hidup di sisi klien (klien <-> HAProxy) tetapi menonaktifkannya di sisi server (HAProxy <-> server).

Beberapa klien kami terhubung ke layanan web kami melalui satelit sehingga latensi ~ 600 ms dan saya pikir dengan mengaktifkan keep-live, itu akan mempercepat sedikit. Apakah saya benar?

Apakah ini didukung oleh Nginx? Apakah ini fitur yang diterapkan secara luas dalam penyeimbang beban perangkat lunak dan perangkat keras lainnya? Apa lagi selain HAProxy?

LostInComputer
sumber

Jawaban:

43

sunting: Jawaban saya hanya mencakup pertanyaan asli yang belum diedit, yang merupakan apakah hal semacam ini tipikal dalam load balancers / reverse proxy. Saya tidak yakin apakah nginx / produk X memiliki dukungan untuk ini, 99,9% pengalaman proksi terbalik saya adalah dengan HAproxy.

Benar. HTTP Keep-Alive di sisi klien, tetapi tidak di sisi server.

Mengapa?

Jika Anda menguraikan beberapa detail, Anda dapat dengan cepat melihat mengapa ini menguntungkan. Untuk contoh ini, mari kita berpura-pura sedang memuat halaman www.example.com dan halaman itu mencakup 3 gambar, img [1-3] .jpg.

Browser memuat halaman, tanpa Keep-Alive

  1. Klien membuat koneksi TCP ke www.example.com pada port 80
  2. Klien melakukan permintaan GET HTTP untuk "/"
  3. Server mengirimkan konten HTML dari URI "/" (yang mencakup tag HTML yang mereferensikan 3 gambar)
  4. Server menutup koneksi TCP
  5. Klien membuat koneksi TCP ke www.example.com pada port 80
  6. Klien melakukan permintaan GET HTTP untuk "/img1.jpg"
  7. Server mengirimkan gambar
  8. Server menutup koneksi TCP
  9. Klien membuat koneksi TCP ke www.example.com pada port 80
  10. Klien melakukan permintaan GET HTTP untuk "/img2.jpg"
  11. Server mengirimkan gambar
  12. Server menutup koneksi TCP
  13. Klien membuat koneksi TCP ke www.example.com pada port 80
  14. Klien melakukan permintaan GET HTTP untuk "/img3.jpg"
  15. Server mengirimkan gambar
  16. Server menutup koneksi TCP

Perhatikan bahwa ada 4 sesi TCP terpisah yang dibuat dan kemudian ditutup.

Browser memuat halaman, dengan Keep-Alive

HTTP Keep-Alive memungkinkan koneksi TCP tunggal untuk melayani beberapa permintaan HTTP, satu demi satu.

  1. Klien membuat koneksi TCP ke www.example.com pada port 80
  2. Klien melakukan permintaan GET HTTP untuk "/", dan juga meminta server untuk menjadikan ini sesi Keep-Alive HTTP.
  3. Server mengirimkan konten HTML dari URI "/" (yang mencakup tag HTML yang mereferensikan 3 gambar)
  4. Server tidak menutup koneksi TCP
  5. Klien melakukannya dan permintaan GET HTTP untuk "/img1.jpg"
  6. Server mengirimkan gambar
  7. Klien melakukannya dan permintaan GET HTTP untuk "/img2.jpg"
  8. Server mengirimkan gambar
  9. Klien melakukannya dan permintaan GET HTTP untuk "/img3.jpg"
  10. Server mengirimkan gambar
  11. Server menutup koneksi TCP jika tidak ada lagi permintaan HTTP yang diterima dalam periode waktu habis HTTP Keep-Alive-nya

Perhatikan bahwa dengan Keep-Alive, hanya 1 koneksi TCP yang dibuat dan akhirnya ditutup.

Mengapa Keep-Alive lebih baik?

Untuk menjawab ini, Anda harus memahami apa yang diperlukan untuk membuat koneksi TCP antara klien dan server. Ini disebut jabat tangan TCP 3 arah.

  1. Klien mengirimkan paket SYN (chronise)
  2. Server mengirimkan kembali SYN (chronise) ACK (nowledgement), SYN-ACK
  3. Klien mengirimkan paket ACK (sekarang)
  4. Koneksi TCP sekarang dianggap aktif oleh klien dan server

Jaringan memiliki latensi, sehingga setiap langkah dalam jabat tangan 3-arah membutuhkan waktu tertentu. Katakanlah bahwa ada 30 ms antara klien dan server, pengiriman paket IP bolak-balik yang diperlukan untuk membangun koneksi TCP berarti dibutuhkan 3 x 30 ms = 90 ms untuk membuat koneksi TCP.

Ini mungkin kedengarannya tidak banyak, tetapi jika kita menganggap bahwa dalam contoh asli kita, kita harus membuat 4 koneksi TCP terpisah, ini menjadi 360ms. Bagaimana jika latensi antara klien dan server adalah 100 ms, bukan 30 ms? Kemudian 4 koneksi kami membutuhkan 1200ms untuk dibangun.

Lebih buruk lagi, halaman web biasa mungkin memerlukan lebih dari hanya 3 gambar untuk memuat, mungkin ada beberapa CSS, JavaScript, gambar atau file lain yang perlu diminta klien. Jika halaman memuat 30 file lain dan latensi klien-server adalah 100 ms, berapa lama kita habiskan membuat koneksi TCP?

  1. Untuk membangun 1 koneksi TCP dibutuhkan 3 x latensi, yaitu 3 x 100 ms = 300 ms.
  2. Kita harus melakukan ini 31 kali, sekali untuk halaman, dan 30 kali untuk setiap file lainnya yang dirujuk oleh halaman. 31 x 300 ms = 9,3 detik.

9,3 detik dihabiskan untuk membuat koneksi TCP untuk memuat halaman web yang mereferensikan 30 file lainnya. Dan itu bahkan tidak menghitung waktu yang dihabiskan untuk mengirim permintaan HTTP dan menerima tanggapan.

Dengan HTTP Keep-Alive, kita hanya perlu membuat 1 koneksi TCP, yang membutuhkan 300ms.

Jika HTTP Keep-Alive begitu hebat, mengapa tidak menggunakannya di sisi server juga?

Proxy reverse HTTP (seperti HAproxy) biasanya digunakan sangat dekat dengan server backend yang mereka proksi. Dalam kebanyakan kasus, latensi antara proxy terbalik dan server backendnya berada di bawah 1 ms, jadi membangun koneksi TCP jauh lebih cepat daripada di antara klien.

Itu hanya setengah alasannya. Server HTTP mengalokasikan sejumlah memori untuk setiap koneksi klien. Dengan Keep-Alive, itu akan membuat koneksi tetap hidup, dan dengan ekstensi itu akan menjaga sejumlah memori yang digunakan di server, sampai batas waktu Keep-Alive tercapai, yang mungkin mencapai 15-an, tergantung pada konfigurasi server .

Jadi jika kita mempertimbangkan efek dari menggunakan Keep-Alive pada sisi server dari HTTP reverse proxy, kami meningkatkan kebutuhan akan memori, tetapi karena latensi antara proxy dan server sangat rendah, kami tidak mendapatkan manfaat nyata dari pengurangan waktu yang diperlukan untuk jabat tangan 3-arah TCP, jadi biasanya lebih baik menonaktifkan Keep-Alive antara proxy dan server web dalam skenario ini.

Penafian: ya, penjelasan ini tidak memperhitungkan fakta bahwa browser biasanya membuat beberapa koneksi HTTP ke server secara paralel. Namun, ada batasan berapa banyak koneksi paralel yang dilakukan browser ke host yang sama, dan biasanya ini masih cukup kecil untuk membuat keep-live diinginkan.

ThatGraemeGuy
sumber
5
Kudos untuk Graeme penjelasan yang luar biasa, saya tidak pernah menghabiskan cukup waktu selama itu untuk menjawab siapa pun yang menanyakan hal ini kepada saya, dan saya pasti akan menyimpan tautan ke pos ini untuk memberikan respons yang sangat jelas sekarang :-)
Willy Tarreau
2
Apakah akan ada keuntungan untuk keepAlive di sisi server jika koneksi antara proxy dan backend adalah https?
avmohan
"Server HTTP mengalokasikan sejumlah memori untuk setiap koneksi klien" ya, tetapi akan ada beberapa koneksi (?) Hanya satu per load-balancer? Tidak satu per klien di Internet (?)
Raedwald
@Redwald, jika penyeimbang beban Anda terbatas untuk membuat koneksi HTTP tunggal ke setiap server yang didukung, Anda akan memiliki waktu yang sangat buruk. :-)
ThatGraemeGuy
7

Nginx mendukung tetap hidup di kedua sisi.

VBart
sumber
Apakah Anda mengatakan tetap hidup berguna untuk backend, jika ada latensi antara proxy dan backends? Juga, berapa jumlah koneksi tetap yang diizinkan yang optimal?
CMCDragonkai
@ CMCDragonkai Jika backend Anda berada di server khusus maka akan berguna untuk menghindari latensi koneksi yang tergantung pada jaringan Anda. Tidak ada nilai emas, angka optimal terutama tergantung pada pengaturan Anda, lingkungan Anda, aplikasi Anda dan pola permintaan.
VBart
Saya berharap dapat menemukan persamaan untuk menyelesaikan ini!
CMCDragonkai
2
Pertanyaannya, ketika saya membacanya, tidak menanyakan apakah nginx mendukung keep-live di hulu, tetapi apakah nginx mendukung menonaktifkan keep-live di sisi hulu.
user45793