Nginx

HTTP 反向代理是否通常在代理連接的客戶端而不是伺服器端啟用 HTTP Keep-Alive?

  • September 12, 2012

HAProxy 能夠在客戶端(客戶端 <-> HAProxy)啟用 HTTP keep-alive,但在伺服器端(HAProxy <-> 伺服器)禁用它。

我們的一些客戶通過衛星連接到我們的 Web 服務,因此延遲約為 600 毫秒,我認為通過啟用 keep-alive,它會加快速度。我對嗎?

Nginx 支持嗎?這是其他軟體和硬體負載平衡器中廣泛實施的功能嗎?除了 HAProxy 還有什麼?

**編輯:**我的回答只涵蓋了原始的未經編輯的問題,即這種事情在負載均衡器/反向代理中是否很典型。我不確定 nginx/product X 是否支持這個,我 99.9% 的反向代理經驗是使用 HAproxy。

正確的。HTTP Keep-Alive 在客戶端,但不在伺服器端。

為什麼?

如果您分解一些細節,您可以快速了解為什麼這是一個好處。對於這個例子,假設我們正在載入一個頁面 www.example.com 並且該頁麵包含 3 個圖像,img

$$ 1-3 $$.jpg。 瀏覽器載入頁面,沒有 Keep-Alive

  1. 客戶端在埠 80 上建立到 www.example.com 的 TCP 連接
  2. 客戶端對“/”執行 HTTP GET 請求
  3. 伺服器發送 URI“/”的 HTML 內容(包括引用 3 個圖像的 HTML 標記)
  4. 伺服器關閉 TCP 連接
  5. 客戶端在埠 80 上建立到 www.example.com 的 TCP 連接
  6. 客戶端對“/img1.jpg”執行 HTTP GET 請求
  7. 伺服器發送圖像
  8. 伺服器關閉 TCP 連接
  9. 客戶端在埠 80 上建立到 www.example.com 的 TCP 連接
  10. 客戶端對“/img2.jpg”執行 HTTP GET 請求
  11. 伺服器發送圖像
  12. 伺服器關閉 TCP 連接
  13. 客戶端在埠 80 上建立到 www.example.com 的 TCP 連接
  14. 客戶端對“/img3.jpg”執行 HTTP GET 請求
  15. 伺服器發送圖像
  16. 伺服器關閉 TCP 連接

請注意,有 4 個單獨的 TCP 會話建立然後關閉。

使用 Keep-Alive 載入頁面的瀏覽器

HTTP Keep-Alive 允許一個 TCP 連接一個接一個地服務多個 HTTP 請求。

  1. 客戶端在埠 80 上建立到 www.example.com 的 TCP 連接
  2. 客戶端對“/”進行 HTTP GET 請求,並要求伺服器將此作為 HTTP Keep-Alive 會話。
  3. 伺服器發送 URI“/”的 HTML 內容(包括引用 3 個圖像的 HTML 標記)
  4. 伺服器沒有關閉TCP 連接
  5. 客戶端執行“/img1.jpg”的 HTTP GET 請求
  6. 伺服器發送圖像
  7. 客戶端執行“/img2.jpg”的 HTTP GET 請求
  8. 伺服器發送圖像
  9. 客戶端執行“/img3.jpg”的 HTTP GET 請求
  10. 伺服器發送圖像
  11. 如果在其 HTTP Keep-Alive 超時期限內沒有收到更多 HTTP 請求,伺服器將關閉 TCP 連接

請注意,使用 Keep-Alive,僅建立 1 個 TCP 連接並最終關閉。

為什麼 Keep-Alive 更好?

要回答這個問題,您必須了解在客戶端和伺服器之間建立 TCP 連接需要什麼。這稱為 TCP 3 次握手。

  1. 客戶端發送一個 SYN(chronise) 數據包
  2. 伺服器發回一個 SYN(chronise) ACK(nowledgement), SYN-ACK
  3. 客戶端發送一個 ACK(nowledgement) 數據包
  4. 客戶端和伺服器現在都認為 TCP 連接處於活動狀態

網路有延遲,因此 3 次握手中的每一步都需要一定的時間。假設客戶端和伺服器之間有 30 毫秒,建立 TCP 連接所需的 IP 數據包來回發送意味著建立 TCP 連接需要 3 x 30 毫秒 = 90 毫秒。

這聽起來可能不多,但如果我們考慮在我們最初的範例中,我們必須建立 4 個單獨的 TCP 連接,這將變為 360 毫秒。如果客戶端和伺服器之間的延遲是 100 毫秒而不是 30 毫秒怎麼辦?然後我們的 4 個連接需要 1200 毫秒才能建立。

更糟糕的是,一個典型的網頁可能需要遠不止 3 張圖片才能載入,還可能有多個 CSS、JavaScript、圖片或其他客戶端需要請求的文件。如果頁面載入了 30 個其他文件並且客戶端-伺服器延遲為 100 毫秒,那麼我們建立 TCP 連接需要多長時間?

  1. 建立 1 個 TCP 連接需要 3 x 延遲,即 3 x 100ms = 300ms。
  2. 我們必須這樣做 31 次,一次用於頁面,另外 30 次用於頁面引用的每個其他文件。31 x 300 毫秒 = 9.3 秒。

建立 TCP 連接以載入引用 30 個其他文件的網頁需要 9.3 秒。這甚至還沒有計算發送 HTTP 請求和接收響應所花費的時間。

使用 HTTP Keep-Alive,我們只需要建立 1 個 TCP 連接,耗時 300 毫秒。

如果 HTTP Keep-Alive 如此出色,為什麼不在伺服器端也使用它呢?

HTTP 反向代理(如 HAproxy)通常部署在非常靠近它們所代理的後端伺服器的位置。在大多數情況下,反向代理與其後端伺服器之間的延遲將低於 1ms,因此建立 TCP 連接比在客戶端之間快得多。

不過,這只是一半的原因。HTTP 伺服器為每個客戶端連接分配一定數量的記憶體。使用 Keep-Alive,它將保持連接處於活動狀態,並且通過擴展,它將在伺服器上保持一定數量的記憶體使用,直到達到 Keep-Alive 超時,可能長達 15 秒,具體取決於伺服器配置.

因此,如果我們考慮在 HTTP 反向代理的伺服器端使用 Keep-Alive 的影響,我們正在增加對記憶體的需求,但是由於代理和伺服器之間的延遲非常低,我們無法從減少 TCP 的 3 次握手所用的時間,因此在這種情況下,最好只禁用代理和 Web 伺服器之間的 Keep-Alive。

免責聲明:是的,這種解釋沒有考慮瀏覽器通常與伺服器建立多個 HTTP 連接的事實。但是,瀏覽器與同一主機建立的並行連接數量是有限的,通常這仍然足夠小,可以滿足保持活動的需要。

引用自:https://serverfault.com/questions/426726