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
- Máy khách thiết lập kết nối TCP tới www.example.com trên cổng 80
- Máy khách thực hiện yêu cầu HTTP GET cho "/"
- 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)
- Máy chủ đóng kết nối TCP
- Máy khách thiết lập kết nối TCP tới www.example.com trên cổng 80
- Khách hàng thực hiện yêu cầu HTTP GET cho "/img1.jpg"
- Máy chủ gửi hình ảnh
- Máy chủ đóng kết nối TCP
- Máy khách thiết lập kết nối TCP tới www.example.com trên cổng 80
- Khách hàng thực hiện yêu cầu HTTP GET cho "/img2.jpg"
- Máy chủ gửi hình ảnh
- Máy chủ đóng kết nối TCP
- Máy khách thiết lập kết nối TCP tới www.example.com trên cổng 80
- Khách hàng thực hiện yêu cầu HTTP GET cho "/img3.jpg"
- Máy chủ gửi hình ảnh
- 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.
- Máy khách thiết lập kết nối TCP tới www.example.com trên cổng 80
- 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.
- 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)
- Máy chủ không đóng kết nối TCP
- Máy khách thực hiện và yêu cầu HTTP GET cho "/img1.jpg"
- Máy chủ gửi hình ảnh
- Máy khách thực hiện và yêu cầu HTTP GET cho "/img2.jpg"
- Máy chủ gửi hình ảnh
- Khách hàng thực hiện và yêu cầu HTTP GET cho "/img3.jpg"
- Máy chủ gửi hình ảnh
- 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.
- Khách hàng gửi một gói SYN (chronise)
- Máy chủ gửi lại một ACK (chronise) ACK (hiện tại), SYN-ACK
- Khách hàng gửi gói ACK (nowledgement)
- 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?
- Để thiết lập 1 kết nối TCP cần 3 lần trễ, tức là 3 x 100ms = 300ms.
- 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.