http tiếp tục tồn tại trong thời đại hiện đại


92

Vì vậy, theo tác giả haproxy, người biết một hoặc hai điều về http:

Keep-live được phát minh để giảm mức sử dụng CPU trên máy chủ khi CPU chậm hơn 100 lần. Nhưng điều chưa được nói là các kết nối liên tục tiêu tốn rất nhiều bộ nhớ trong khi không ai có thể sử dụng được ngoại trừ khách hàng đã mở chúng. Ngày nay vào năm 2009, CPU rất rẻ và bộ nhớ vẫn bị giới hạn ở một vài gigabyte bởi kiến ​​trúc hoặc giá cả. Nếu một trang web cần được duy trì, thì có một vấn đề thực sự. Các trang web được tải nhiều thường vô hiệu hóa tính năng duy trì để hỗ trợ số lượng khách hàng đồng thời tối đa. Nhược điểm thực sự của việc không giữ được tính năng duy trì là độ trễ để tìm nạp các đối tượng tăng lên một chút. Các trình duyệt tăng gấp đôi số lượng kết nối đồng thời trên các trang web không lưu giữ để bù đắp cho điều này.

(từ http://haproxy.1wt.eu/ )

Điều này có phù hợp với kinh nghiệm của những người khác không? tức là không có sự sống sót - kết quả bây giờ hầu như không đáng chú ý? (có lẽ điều đáng chú ý là với websockets, v.v. - kết nối được giữ ở trạng thái "mở" bất kể trạng thái duy trì hoạt động - đối với các ứng dụng rất nhạy). Hiệu quả có lớn hơn đối với những người ở xa máy chủ - hoặc nếu có nhiều hiện vật cần tải từ cùng một máy chủ khi tải một trang? (Tôi nghĩ những thứ như CSS, hình ảnh và JS ngày càng đến từ các CDN thân thiện với bộ nhớ cache).

Suy nghĩ?

(không chắc đây có phải là thứ của serverfault.com hay không, nhưng tôi sẽ không đăng chéo cho đến khi ai đó bảo tôi chuyển nó đến đó).


1
Điều đáng chú ý là ở những nơi khác trong tài liệu về haproxy vẫn tồn tại được đề cập đến bằng các thuật ngữ khác có lợi hơn. Tôi rất muốn nghe về trải nghiệm của mọi người, đặc biệt là đối với dịch vụ lưu trữ hàng loạt.
Michael Neale

"Nhận một web / ứng dụng-máy chủ được thiết kế tốt hơn"? :-) Các thiết kế mới hơn (chẳng hạn như Jetty) với việc xử lý kết nối tiếp tục (-like) về cơ bản giảm thiểu các vấn đề về bộ nhớ / luồng. Ngoài ra, "vài GB" âm thanh như một thuật ngữ 2008/2009 máy chủ ;-)

3
Nó giống như một trò đùa đối với tôi. RTT bổ sung liên quan đến việc thiết lập một ổ cắm mới là một giới hạn vật lý cứng thường đủ dài để con người có thể phát hiện được và không thể giảm trong các định luật vật lý đã biết. Ngược lại, RAM rẻ, ngày càng rẻ, và không có lý do gì để một ổ cắm nhàn rỗi sử dụng nhiều hơn một vài kB của nó.
Will Dean

2
nhưng điều thú vị là đây không chỉ là lý thuyết - đây là tác giả của haproxy. Tất cả những gì khác tôi nghe là lý thuyết và giả định.
Michael Neale

Câu trả lời:


141

Xin chào vì tôi là tác giả của trích dẫn này, tôi sẽ trả lời :-)

Có hai vấn đề lớn trên các trang web lớn: kết nối đồng thời và độ trễ. Kết nối đồng thời là do các máy khách chậm mất nhiều thời gian để tải xuống nội dung và do trạng thái kết nối không hoạt động. Các trạng thái kết nối không hoạt động đó là do việc sử dụng lại kết nối để tìm nạp nhiều đối tượng, được gọi là giữ nguyên, còn tăng thêm do độ trễ. Khi máy khách ở rất gần máy chủ, nó có thể sử dụng kết nối chuyên sâu và đảm bảo nó hầu như không bao giờ ở chế độ rỗi. Tuy nhiên, khi trình tự kết thúc, không ai quan tâm đến việc nhanh chóng đóng kênh và kết nối vẫn mở và không được sử dụng trong một thời gian dài. Đó là lý do tại sao nhiều người đề nghị sử dụng thời gian chờ duy trì hoạt động rất thấp. Trên một số máy chủ như Apache, thời gian chờ thấp nhất mà bạn có thể đặt là một giây và thường là quá nhiều để duy trì tải cao: nếu bạn có 20000 khách hàng ở phía trước và họ tìm nạp trung bình một đối tượng mỗi giây, bạn sẽ có 20000 kết nối đó được thiết lập vĩnh viễn. 20000 kết nối đồng thời trên một máy chủ mục đích chung như Apache là rất lớn, sẽ yêu cầu từ 32 đến 64 GB RAM tùy thuộc vào những gì mô-đun được tải và bạn có thể không hy vọng tăng cao hơn nhiều ngay cả bằng cách thêm RAM. Trên thực tế, đối với 20000 máy khách, bạn thậm chí có thể thấy 40000 đến 60000 kết nối đồng thời trên máy chủ vì trình duyệt sẽ cố gắng thiết lập 2 đến 3 kết nối nếu chúng có nhiều đối tượng để tìm nạp. và bạn có thể không hy vọng sẽ tăng cao hơn nhiều ngay cả khi thêm RAM. Trên thực tế, đối với 20000 máy khách, bạn thậm chí có thể thấy 40000 đến 60000 kết nối đồng thời trên máy chủ vì trình duyệt sẽ cố gắng thiết lập 2 đến 3 kết nối nếu chúng có nhiều đối tượng cần tìm nạp. và bạn có thể không hy vọng sẽ tăng cao hơn nhiều ngay cả khi thêm RAM. Trên thực tế, đối với 20000 máy khách, bạn thậm chí có thể thấy 40000 đến 60000 kết nối đồng thời trên máy chủ vì trình duyệt sẽ cố gắng thiết lập 2 đến 3 kết nối nếu chúng có nhiều đối tượng để tìm nạp.

Nếu bạn đóng kết nối sau mỗi đối tượng, số lượng kết nối đồng thời sẽ giảm đáng kể. Thật vậy, nó sẽ giảm theo một hệ số tương ứng với thời gian trung bình để tải một đối tượng theo thời gian giữa các đối tượng. Nếu bạn cần 50 mili giây để tải xuống một đối tượng (ảnh thu nhỏ, một nút, v.v.) và bạn tải xuống trung bình 1 đối tượng mỗi giây như trên, thì bạn sẽ chỉ có 0,05 kết nối cho mỗi máy khách, tức là chỉ 1000 kết nối đồng thời cho 20000 máy khách.

Bây giờ thời gian để thiết lập các kết nối mới sẽ được đếm. Khách hàng ở xa sẽ gặp phải độ trễ khó chịu. Trước đây, các trình duyệt thường sử dụng một lượng lớn các kết nối đồng thời khi tính năng giữ mạng bị vô hiệu hóa. Tôi nhớ con số 4 trên MSIE và 8 trên Netscape. Điều này thực sự sẽ chia độ trễ trung bình trên mỗi đối tượng cho bấy nhiêu. Giờ đây, tính năng duy trì tồn tại ở khắp mọi nơi, chúng tôi không còn thấy con số cao đó nữa, bởi vì làm như vậy sẽ làm tăng thêm tải trên các máy chủ từ xa và các trình duyệt sẽ chăm sóc bảo vệ cơ sở hạ tầng của Internet.

Điều này có nghĩa là với các trình duyệt ngày nay, khó có thể khiến các dịch vụ không tồn tại đáp ứng nhiều như các dịch vụ còn tồn tại. Ngoài ra, một số trình duyệt (ví dụ: Opera) sử dụng heuristics để cố gắng sử dụng pipelinining. Pipelining là một cách hiệu quả để sử dụng giữ nguyên, vì nó gần như loại bỏ độ trễ bằng cách gửi nhiều yêu cầu mà không cần đợi phản hồi. Tôi đã thử nó trên một trang có 100 bức ảnh nhỏ và lần truy cập đầu tiên nhanh hơn khoảng gấp đôi so với khi không giữ mạng, nhưng lần truy cập tiếp theo nhanh hơn khoảng 8 lần, bởi vì phản hồi rất nhỏ nên chỉ tính độ trễ (chỉ "304" phản hồi).

Tôi muốn nói rằng lý tưởng nhất là chúng ta nên có một số điều chỉnh trong trình duyệt để làm cho chúng giữ cho các kết nối tồn tại giữa các đối tượng được tìm nạp và ngay lập tức loại bỏ nó khi trang hoàn tất. Nhưng chúng tôi không thấy điều đó đáng tiếc.

Vì lý do này, một số trang web cần cài đặt các máy chủ có mục đích chung như Apache ở mặt trước và các trang web phải hỗ trợ một lượng lớn khách hàng thường phải tắt tính năng giữ mạng. Và để buộc các trình duyệt tăng số lượng kết nối, họ sử dụng nhiều tên miền để có thể tải song song các bản tải xuống. Nó đặc biệt có vấn đề trên các trang web sử dụng nhiều SSL vì thiết lập kết nối thậm chí còn cao hơn vì có thêm một chuyến khứ hồi.

Điều thường được quan sát hiện nay là các trang web như vậy thích cài đặt các giao diện người dùng nhẹ như haproxy hoặc nginx, không có vấn đề gì khi xử lý hàng chục đến hàng trăm nghìn kết nối đồng thời, chúng cho phép duy trì hoạt động ở phía máy khách và tắt nó trên Bên Apache. Ở khía cạnh này, chi phí thiết lập kết nối gần như vô hiệu về mặt CPU và không đáng kể về mặt thời gian. Bằng cách đó, điều này mang lại lợi ích tốt nhất của cả hai thế giới: độ trễ thấp do vẫn tồn tại với thời gian chờ rất thấp ở phía máy khách và số lượng kết nối thấp ở phía máy chủ. Mọi người đều vui vẻ :-)

Một số sản phẩm thương mại cải thiện hơn nữa điều này bằng cách sử dụng lại các kết nối giữa bộ cân bằng tải phía trước và máy chủ và ghép tất cả các kết nối máy khách qua chúng. Khi các máy chủ gần LB, mức tăng không cao hơn nhiều so với giải pháp trước đó, nhưng nó thường sẽ yêu cầu sự điều chỉnh trên ứng dụng để đảm bảo không có nguy cơ chuyển phiên giữa những người dùng do việc chia sẻ kết nối không mong muốn giữa nhiều người dùng . Về lý thuyết, điều này không bao giờ nên xảy ra. Thực tế khác nhiều :-)


1
Cảm ơn bạn đã trả lời đầy đủ và toàn diện! Tôi hơi bối rối trước nhiều bình luận khác nhau trên trang về việc duy trì sự sống - nhưng điều này đều có ý nghĩa.
Michael Neale

Điều thú vị là - tôi đã quan sát thấy Chrome trên linux sử dụng lại một kết nối được duy trì trong vài giây - tức là mất thời gian để mở một tab khác - tab khác này là một tên máy chủ khác, nhưng được giải quyết thông qua ký tự đại diện DNS cho cùng một máy chủ (hàng loạt lưu trữ ảo) - và do đó đã sử dụng lại cùng một kết nối! (điều này gây cho tôi một số ngạc nhiên, không phải là loại tốt - rõ ràng nếu giữ sống chỉ là phía khách hàng thì tốt).
Michael Neale

Tất cả những gì tôi nghe được là "sử dụng bất cứ thứ gì khác ngoài apache và nó không phải là vấn đề lớn". Những gì tôi ngoại suy là "vô hiệu hóa mod_php và hành khách và sau đó thậm chí apache có thể có cơ hội chiến đấu".
coolaj86

@ CoolAJ86: điểm tuyệt đối là không nên bash Apache, và cá nhân tôi sử dụng nó. Vấn đề là máy chủ càng chung chung, bạn có ít tùy chọn nhất để mở rộng quy mô. Một số mô-đun yêu cầu mô hình pre-fork thì bạn không thể mở rộng quy mô kết nối với số lượng lớn. Nhưng như đã giải thích, đó không phải là vấn đề lớn vì bạn có thể kết hợp nó với một thành phần miễn phí khác như haproxy. Tại sao bất cứ ai sẽ thay thế mọi thứ trong trường hợp này? Cài đặt haproxy tốt hơn là phải thực hiện lại ứng dụng của bạn một cách rắc rối bằng một máy chủ khác!
Willy Tarreau

22

Trong những năm kể từ khi điều này được viết (và đăng ở đây trên stackoverflow), chúng tôi hiện có các máy chủ như nginx đang ngày càng phổ biến.

Ví dụ, nginx có thể giữ 10.000 kết nối duy trì mở trong một quá trình duy nhất với chỉ 2,5 MB (megabyte) RAM. Trên thực tế, thật dễ dàng để mở hàng nghìn kết nối với rất ít RAM và giới hạn duy nhất bạn sẽ gặp phải sẽ là các giới hạn khác như số lượng xử lý tệp đang mở hoặc kết nối TCP.

Keep-live là một vấn đề không phải do bất kỳ vấn đề nào với bản thân thông số kỹ thuật giữ tồn tại mà là do mô hình mở rộng quy trình dựa trên quy trình của Apache và các keep-alives đã tấn công vào một máy chủ có kiến ​​trúc không được thiết kế để thích ứng với nó.

Đặc biệt có vấn đề là Apache Prefork + mod_php + keep-alives. Đây là một mô hình mà mọi kết nối sẽ tiếp tục chiếm tất cả bộ nhớ RAM mà một tiến trình PHP chiếm, ngay cả khi nó hoàn toàn không hoạt động và chỉ mở để duy trì hoạt động. Điều này không thể mở rộng. Nhưng các máy chủ không nhất thiết phải được thiết kế theo cách này - không có lý do cụ thể nào mà máy chủ cần giữ mọi kết nối tồn tại trong một quy trình riêng biệt (đặc biệt là không phải khi mọi quy trình như vậy đều có trình thông dịch PHP đầy đủ). PHP-FPM và một mô hình xử lý máy chủ dựa trên sự kiện như trong nginx giải quyết vấn đề một cách thanh lịch.

Cập nhật 2015:

SPDY và ​​HTTP / 2 thay thế chức năng duy trì hoạt động của HTTP bằng một thứ gì đó thậm chí còn tốt hơn: khả năng không chỉ duy trì kết nối và thực hiện nhiều yêu cầu và phản hồi qua nó, mà còn để chúng được ghép lại, vì vậy các phản hồi có thể được gửi theo bất kỳ thứ tự nào , và song song, thay vì chỉ theo thứ tự mà chúng được yêu cầu. Điều này ngăn chặn các phản hồi chậm chặn các phản hồi nhanh hơn và loại bỏ sự cám dỗ đối với các trình duyệt để mở nhiều kết nối song song với một máy chủ. Những công nghệ này làm nổi bật thêm những điểm bất cập của cách tiếp cận mod_php và những lợi ích của một thứ như máy chủ web dựa trên sự kiện (hoặc ít nhất là đa luồng) được kết hợp riêng với một thứ như PHP-FPM.


2

sự hiểu biết của tôi là nó không liên quan rất nhiều đến CPU, nhưng độ trễ khi mở các ổ cắm lặp đi lặp lại ở bên kia thế giới. ngay cả khi bạn có băng thông vô hạn, độ trễ kết nối sẽ làm chậm toàn bộ quá trình. khuếch đại nếu trang của bạn có hàng chục đối tượng. Ngay cả một kết nối liên tục cũng có độ trễ yêu cầu / phản hồi nhưng nó giảm khi trung bình bạn có 2 ổ cắm, một ổ cắm sẽ truyền dữ liệu trong khi ổ cắm kia có thể bị chặn. Ngoài ra, một bộ định tuyến sẽ không bao giờ cho rằng một ổ cắm được kết nối trước khi cho phép bạn ghi vào nó. Nó cần một cái bắt tay khứ hồi đầy đủ. một lần nữa, tôi không tự nhận mình là một chuyên gia, nhưng đây là cách tôi luôn thấy nó. điều thực sự tuyệt vời là một giao thức ASYNC hoàn toàn (không, không phải là một giao thức hoàn toàn ốm yếu).


vâng - đó sẽ là giả định của tôi. có thể nó là một sự cân bằng - có một điểm mà độ trễ (do khoảng cách) có nghĩa là rằng nó là một vấn đề thực sự
Michael Neale

ok, vì vậy kiểu chữ hiện đại sẽ yêu cầu bạn kết nối với một proxy ở gần (có thể). nhưng sau đó bạn có mở rộng câu hỏi cho các proxy ẩm ướt hơn có nên sử dụng các kết nối liên tục không?
catchpolenet,

@Michael Neale cũng vậy, vì những thứ như TCP khởi động chậm, hình phạt độ trễ thực tế còn tồi tệ hơn nhiều so với bạn mong đợi.
MartinodF

có thể sự đánh đổi là khoảng thời gian chờ ngắn hơn nhiều. nếu bạn có các yêu cầu được sao lưu, tại sao phải tắt ổ cắm và bắt đầu lại? thậm chí 1 giây sẽ cho phép một trang tải hoàn toàn liên tục và sau đó tắt các ổ cắm ngay sau đó.
catchpolenet

2

Bí mật lưu giữ rất dài có thể hữu ích nếu bạn đang sử dụng CDN "gốc kéo" chẳng hạn như CloudFront hoặc CloudFlare. Trên thực tế, điều này có thể hoạt động nhanh hơn so với không có CDN, ngay cả khi bạn đang phân phối nội dung động hoàn toàn.

Nếu bạn đã giữ bí danh từ lâu để mỗi PoP về cơ bản có kết nối vĩnh viễn với máy chủ của bạn, thì lần đầu tiên người dùng truy cập trang web của bạn, họ có thể thực hiện bắt tay TCP nhanh với PoP cục bộ của họ thay vì bắt tay chậm với bạn. (Bản thân Light mất khoảng 100ms để đi nửa vòng trái đất qua cáp quang và việc thiết lập kết nối TCP yêu cầu ba gói được truyền qua lại. SSL yêu cầu ba chuyến khứ hồi .)


1
Tôi đã bị cám dỗ để +1, nhưng sau đó đoạn thứ hai của bạn có nhận xét không chính xác về ánh sáng chỉ mất 10 mili giây để đi nửa vòng trái đất. 10 ms tốc độ đèn trong chân không là 3000 km và 10 ms tốc độ ánh sáng trong sợi quang là không quá 2000 km; nửa vòng trái đất (dọc theo bề mặt) là 20.000 km. Vì vậy, đó sẽ là 100 mili giây --- nếu chỉ có sợi quang của bạn đi thẳng từ London đến Sydney thay vì có khả năng đi vòng quanh châu Phi bằng đường biển hoặc đi một tuyến đường dài đến Hawaii ...
kim tự tháp

@pyramids Bạn nói đúng, hoặc là tôi đã đánh máy, hoặc chỉ là ngu ngốc. Sẽ nâng cấp.
mjs
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.