Các proxy ngược HTTP thường kích hoạt HTTP Keep-Alive ở phía máy khách của kết nối proxy chứ không phải ở phía máy chủ?


30

HAProxy có khả năng cho phép giữ HTTP ở phía máy khách (máy khách <-> HAProxy) nhưng vô hiệu hóa nó ở phía máy chủ (máy chủ HAProxy <->).

Một số khách hàng của chúng tôi kết nối với dịch vụ web của chúng tôi qua vệ tinh nên độ trễ là ~ 600ms và tôi nghĩ rằng bằng cách cho phép duy trì sự sống, nó sẽ tăng tốc mọi thứ lên một chút. Tôi có đúng không

Điều này có được hỗ trợ bởi Nginx không? Đây có phải là một tính năng được triển khai rộng rãi trong các bộ cân bằng tải phần mềm và phần cứng khác không? Còn gì khác ngoài HAProxy?

Câu trả lời:


43

chỉnh sửa: Câu trả lời của tôi chỉ bao gồm câu hỏi chưa được chỉnh sửa ban đầu, đó là liệu loại điều này có điển hình trong các bộ cân bằng tải / proxy ngược hay không. Tôi không chắc liệu nginx / sản phẩm X có hỗ trợ cho việc này hay không, 99,9% trải nghiệm ủy quyền ngược của tôi là với HAproxy.

Chính xác. HTTP Keep-Alive ở phía máy khách, nhưng không phải ở phía máy chủ.

Tại sao?

Nếu bạn chia nhỏ một vài chi tiết, bạn có thể nhanh chóng thấy tại sao đây là một lợi ích. Trong ví dụ này, hãy giả vờ rằng chúng tôi đang tải một trang www.example.com và trang đó bao gồm 3 hình ảnh, img [1-3] .jpg.

Trình duyệt đang tải một trang mà không cần Keep-Alive

  1. Máy khách thiết lập kết nối TCP tới www.example.com trên cổng 80
  2. Máy khách thực hiện yêu cầu HTTP GET cho "/"
  3. Máy chủ gửi nội dung HTML của URI "/" (bao gồm các thẻ HTML tham chiếu 3 hình ảnh)
  4. Máy chủ đóng kết nối TCP
  5. Máy khách thiết lập kết nối TCP tới www.example.com trên cổng 80
  6. Khách hàng thực hiện yêu cầu HTTP GET cho "/img1.jpg"
  7. Máy chủ gửi hình ảnh
  8. Máy chủ đóng kết nối TCP
  9. Máy khách thiết lập kết nối TCP tới www.example.com trên cổng 80
  10. Khách hàng thực hiện yêu cầu HTTP GET cho "/img2.jpg"
  11. Máy chủ gửi hình ảnh
  12. Máy chủ đóng kết nối TCP
  13. Máy khách thiết lập kết nối TCP tới www.example.com trên cổng 80
  14. Khách hàng thực hiện yêu cầu HTTP GET cho "/img3.jpg"
  15. Máy chủ gửi hình ảnh
  16. Máy chủ đóng kết nối TCP

Lưu ý rằng có 4 phiên TCP riêng biệt được thiết lập và sau đó đóng lại.

Trình duyệt đang tải một trang, với Keep-Alive

HTTP Keep-Alive cho phép một kết nối TCP duy nhất phục vụ nhiều yêu cầu HTTP, lần lượt từng yêu cầu.

  1. Máy khách thiết lập kết nối TCP tới www.example.com trên cổng 80
  2. Máy khách thực hiện yêu cầu HTTP GET cho "/" và cũng yêu cầu máy chủ thực hiện phiên HTTP Keep-Alive này.
  3. Máy chủ gửi nội dung HTML của URI "/" (bao gồm các thẻ HTML tham chiếu 3 hình ảnh)
  4. Máy chủ không đóng kết nối TCP
  5. Máy khách thực hiện và yêu cầu HTTP GET cho "/img1.jpg"
  6. Máy chủ gửi hình ảnh
  7. Máy khách thực hiện và yêu cầu HTTP GET cho "/img2.jpg"
  8. Máy chủ gửi hình ảnh
  9. Khách hàng thực hiện và yêu cầu HTTP GET cho "/img3.jpg"
  10. Máy chủ gửi hình ảnh
  11. Máy chủ sẽ đóng kết nối TCP nếu không nhận được thêm yêu cầu HTTP nào trong khoảng thời gian chờ HTTP Keep-Alive của nó

Lưu ý rằng với Keep-Alive, chỉ có 1 kết nối TCP được thiết lập và cuối cùng bị đóng.

Tại sao Keep-Alive tốt hơn?

Để trả lời điều này, bạn phải hiểu những gì cần thiết để thiết lập kết nối TCP giữa máy khách và máy chủ. Đây được gọi là bắt tay 3 bước TCP.

  1. Khách hàng gửi một gói SYN (chronise)
  2. Máy chủ gửi lại một ACK (chronise) ACK (hiện tại), SYN-ACK
  3. Khách hàng gửi gói ACK (nowledgement)
  4. Kết nối TCP hiện được coi là hoạt động bởi cả máy khách và máy chủ

Mạng có độ trễ, vì vậy mỗi bước trong bắt tay 3 bước cần một khoảng thời gian nhất định. Hãy nói rằng có 30ms giữa máy khách và máy chủ, việc gửi qua lại các gói IP cần thiết để thiết lập kết nối TCP có nghĩa là phải mất 3 x 30ms = 90ms để thiết lập kết nối TCP.

Điều này nghe có vẻ không nhiều, nhưng nếu chúng ta xem xét rằng trong ví dụ ban đầu của mình, chúng ta phải thiết lập 4 kết nối TCP riêng biệt, điều này trở thành 360ms. Điều gì xảy ra nếu độ trễ giữa máy khách và máy chủ là 100ms thay vì 30ms? Sau đó, 4 kết nối của chúng tôi đang mất 1200ms để thiết lập.

Thậm chí tệ hơn, một trang web thông thường có thể yêu cầu nhiều hơn chỉ 3 hình ảnh để tải, có thể có nhiều tệp CSS, JavaScript, hình ảnh hoặc các tệp khác mà khách hàng cần yêu cầu. Nếu trang tải 30 tệp khác và độ trễ của máy khách-máy chủ là 100ms, chúng ta sẽ mất bao lâu để thiết lập kết nối TCP?

  1. Để thiết lập 1 kết nối TCP cần 3 lần trễ, tức là 3 x 100ms = 300ms.
  2. Chúng tôi phải làm điều này 31 lần, một lần cho trang và 30 lần khác cho mỗi tệp được tham chiếu bởi trang. 31 x 300ms = 9,3 giây.

9,3 giây dành cho việc thiết lập kết nối TCP để tải trang web tham chiếu 30 tệp khác. Và điều đó thậm chí không tính thời gian gửi yêu cầu HTTP và nhận phản hồi.

Với HTTP Keep-Alive, chúng tôi chỉ cần thiết lập 1 kết nối TCP, mất 300ms.

Nếu HTTP Keep-Alive tuyệt vời như vậy, tại sao bạn cũng không sử dụng nó ở phía máy chủ?

Các proxy ngược HTTP (như HAproxy) thường được triển khai rất gần với các máy chủ phụ trợ mà họ đang ủy quyền. Trong hầu hết các trường hợp, độ trễ giữa proxy ngược và máy chủ phụ trợ của nó sẽ dưới 1ms, do đó, việc thiết lập kết nối TCP nhanh hơn nhiều so với giữa máy khách.

Đó chỉ là một nửa lý do. Một máy chủ HTTP phân bổ một lượng bộ nhớ nhất định cho mỗi kết nối máy khách. Với Keep-Alive, nó sẽ duy trì kết nối và với phần mở rộng, nó sẽ giữ một lượng bộ nhớ nhất định được sử dụng trên máy chủ, cho đến khi hết thời gian chờ Keep-Alive, có thể lên đến 15 giây, tùy thuộc vào cấu hình máy chủ .

Vì vậy, nếu chúng tôi xem xét các tác động của việc sử dụng Keep-Alive ở phía máy chủ của proxy ngược HTTP, chúng tôi sẽ tăng nhu cầu về bộ nhớ, nhưng vì độ trễ giữa proxy và máy chủ quá thấp, chúng tôi không nhận được lợi ích thực sự từ giảm thời gian thực hiện cho bắt tay 3 bước của TCP, do đó, tốt hơn hết là bạn chỉ nên tắt Keep-Alive giữa proxy và máy chủ web trong trường hợp này.

Tuyên bố miễn trừ trách nhiệm: có, giải thích này không tính đến thực tế là các trình duyệt thường thiết lập song song nhiều kết nối HTTP đến một máy chủ. Tuy nhiên, có một giới hạn đối với số lượng kết nối song song mà một trình duyệt sẽ thực hiện với cùng một máy chủ và thông thường, điều này vẫn đủ nhỏ để khiến cho cuộc sống vẫn được mong muốn.


5
Kudos cho lời giải thích tuyệt vời Graeme, tôi chưa bao giờ dành đủ thời gian cho câu trả lời dài đó cho bất cứ ai hỏi tôi điều này, và tôi chắc chắn sẽ giữ một liên kết đến bài đăng này để phục vụ như một phản hồi rất rõ ràng bây giờ :-)
Willy Tarreau

2
Sẽ có một lợi thế cho keepAlive ở phía máy chủ nếu kết nối giữa proxy và phụ trợ là https?
avmohan

"Máy chủ HTTP phân bổ một lượng bộ nhớ nhất định cho mỗi kết nối máy khách" có, nhưng sẽ có một vài trong số các kết nối đó (?) Chỉ có một cho mỗi bộ cân bằng tải? Không phải một khách hàng trên Internet (?)
Raedwald

@Raedwald, nếu bộ cân bằng tải của bạn bị giới hạn trong việc tạo một kết nối HTTP duy nhất cho mỗi máy chủ được hỗ trợ, bạn sẽ có một khoảng thời gian khá tồi tệ. :-)
ThatGraemeGuy

7

Nginx hỗ trợ giữ cho cả hai bên.


Bạn có nói giữ cho sống là hữu ích cho phụ trợ, nếu có độ trễ giữa proxy và phụ trợ không? Ngoài ra, số lượng tối ưu của các kết nối còn sống được cho phép là gì?
CMCDragonkai

@CMCDragonkai Nếu phụ trợ của bạn được đặt trên các máy chủ chuyên dụng thì có thể hữu ích để tránh độ trễ kết nối phụ thuộc vào mạng của bạn. Không có ý nghĩa vàng, con số tối ưu chủ yếu phụ thuộc vào thiết lập, môi trường của bạn, ứng dụng và mẫu yêu cầu của bạn.
VBart

Tôi hy vọng sẽ tìm thấy một phương trình để giải quyết điều này!
CMCDragonkai

2
Câu hỏi, như tôi đã đọc, không phải là hỏi liệu nginx có hỗ trợ duy trì sự sống ở thượng nguồn hay không, nhưng liệu nginx có hỗ trợ vô hiệu hóa việc tiếp tục sống ở phía thượng nguồn hay không.
dùng45793
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.