HTML WebSockets có duy trì kết nối mở cho mỗi khách hàng không? Liệu quy mô này?


159

Tôi tò mò liệu có ai có bất kỳ thông tin nào về khả năng mở rộng của HTML WebSockets không. Đối với tất cả mọi thứ tôi đã đọc, dường như mọi khách hàng sẽ duy trì một đường dây liên lạc mở với máy chủ. Tôi chỉ tự hỏi làm thế nào quy mô đó và có bao nhiêu kết nối WebSocket mở mà một máy chủ có thể xử lý. Có thể để các kết nối đó mở không phải là một vấn đề trong thực tế, nhưng nó cảm thấy như vậy.


1
Không có thứ gọi là HTML WebSocket. Ý bạn là HTTP WebSocket.
Hầu tước Lorne

Câu trả lời:


209

Trong hầu hết các cách, WebSockets có thể sẽ mở rộng tốt hơn các yêu cầu AJAX / HTML. Tuy nhiên, điều đó không có nghĩa là WebSockets là sự thay thế cho tất cả việc sử dụng AJAX / HTML.

Bản thân mỗi kết nối TCP tiêu tốn rất ít về tài nguyên máy chủ. Thường thì việc thiết lập kết nối có thể tốn kém nhưng việc duy trì kết nối nhàn rỗi thì gần như miễn phí. Giới hạn đầu tiên thường gặp là số lượng bộ mô tả tệp tối đa (ổ cắm tiêu thụ bộ mô tả tệp) có thể được mở đồng thời. Điều này thường mặc định là 1024 nhưng có thể dễ dàng được cấu hình cao hơn.

Bạn đã bao giờ thử cấu hình một máy chủ web để hỗ trợ hàng chục ngàn máy khách AJAX đồng thời chưa? Thay đổi các máy khách đó thành các máy khách WebSockets và nó có thể khả thi.

Các kết nối HTTP, trong khi chúng không tạo các tệp đang mở hoặc sử dụng số cổng trong một thời gian dài, thì đắt hơn về mọi mặt:

  • Mỗi kết nối HTTP mang theo rất nhiều hành lý không được sử dụng hầu hết thời gian: cookie, loại nội dung, độ dài conetent, tác nhân người dùng, id máy chủ, ngày, sửa đổi lần cuối, v.v. Sau khi kết nối WebSockets được thiết lập, chỉ dữ liệu theo yêu cầu của ứng dụng cần phải được gửi qua lại.

  • Thông thường, các máy chủ HTTP được cấu hình để ghi nhật ký bắt đầu và hoàn thành mọi yêu cầu HTTP chiếm thời gian của đĩa và CPU. Nó sẽ trở thành tiêu chuẩn để ghi nhật ký bắt đầu và hoàn thành dữ liệu WebSockets, nhưng trong khi kết nối WebSockets thực hiện chuyển song công, sẽ không có bất kỳ chi phí đăng nhập bổ sung nào (ngoại trừ ứng dụng / dịch vụ nếu được thiết kế để làm như vậy).

  • Thông thường, các ứng dụng tương tác sử dụng AJAX hoặc liên tục thăm dò ý kiến ​​hoặc sử dụng một số loại cơ chế thăm dò dài. WebSockets là một cách sạch hơn (và tài nguyên thấp hơn) để thực hiện mô hình nhiều sự kiện hơn trong đó máy chủ và máy khách thông báo cho nhau khi họ có điều gì đó để báo cáo về kết nối hiện có.

  • Hầu hết các máy chủ web phổ biến trong sản xuất đều có một nhóm các quy trình (hoặc luồng) để xử lý các yêu cầu HTTP. Khi áp suất tăng kích thước của nhóm sẽ tăng lên vì mỗi quy trình / luồng xử lý một yêu cầu HTTP tại một thời điểm. Mỗi tiến trình / luồng bổ sung sử dụng nhiều bộ nhớ hơn và tạo các tiến trình / luồng mới tốn kém hơn một chút so với việc tạo các kết nối ổ cắm mới (điều mà các tiến trình / luồng đó vẫn phải làm). Hầu hết các khung máy chủ WebSockets phổ biến đang đi theo lộ trình sự kiện có xu hướng mở rộng và hoạt động tốt hơn.

Lợi ích chính của WebSockets sẽ là các kết nối có độ trễ thấp hơn cho các ứng dụng web tương tác. Nó sẽ mở rộng quy mô tốt hơn và tiêu thụ ít tài nguyên máy chủ hơn HTTP AJAX / cuộc thăm dò dài (giả sử ứng dụng / máy chủ được thiết kế đúng cách), nhưng độ trễ thấp hơn IMO là lợi ích chính của WebSockets vì nó sẽ cho phép các lớp ứng dụng web mới không thể thực hiện được với chi phí hiện tại và độ trễ của AJAX / cuộc thăm dò dài.

Khi tiêu chuẩn WebSockets trở nên hoàn thiện hơn và có sự hỗ trợ rộng hơn, sẽ có ý nghĩa khi sử dụng nó cho hầu hết các ứng dụng web tương tác mới cần liên lạc thường xuyên với máy chủ. Đối với các ứng dụng web tương tác hiện tại, nó thực sự sẽ phụ thuộc vào mức độ mô hình AJAX / cuộc thăm dò dài hiện tại đang hoạt động tốt như thế nào. Nỗ lực chuyển đổi sẽ không tầm thường nên trong nhiều trường hợp, chi phí sẽ không đáng để hưởng lợi.

Cập nhật :

Liên kết hữu ích: 600k kết nối websocket đồng thời trên AWS bằng Node.js


4
Anser tuyệt vời. Cảm ơn bạn đã dành thời gian trả lời.
Ryan Montgomery

7
Mặc dù vậy, tôi vẫn không biết cách chia tỷ lệ khi bạn chạm tường. Đúng là WebSockets tiêu thụ ít tài nguyên hơn (chúng có tỷ lệ theo chiều dọc), nhưng HTTP rất tốt cho việc mở rộng theo chiều ngang. Về lý thuyết tôi có thể thêm máy chủ để mở rộng quy mô vô tận. Tôi đã luôn bối rối về cách mở rộng quy mô khi bạn sử dụng hết dung lượng của một hộp. Suy nghĩ?
Sean Clark Hess

6
@Sean. WebSockets không nhất thiết phải tệ hơn khi mở rộng theo chiều ngang. Nó chỉ mở ra các ứng dụng mới mà không nhất thiết phải mở rộng dễ dàng. Ví dụ: để phục vụ dữ liệu tĩnh, một loạt các máy chủ WebSocket sẽ có quy mô tương đương (hoặc tốt hơn) so với một loạt các máy chủ HTTP. Một trò chơi thời gian thực có độ trễ thấp rất khó để mở rộng bất kể việc vận chuyển (và nó không thực sự khả thi khi sử dụng HTTP). Câu hỏi thực sự là mức độ dữ liệu / ứng dụng của bạn. Nếu tỷ lệ đó, thì sự lựa chọn HTTP vs WebSockets của bạn nên dựa trên các yếu tố khác: độ trễ, tùy chọn triển khai, hỗ trợ trình duyệt, v.v.
kanaka

2
Một điều chỉnh - kết nối TCP bao gồm cổng đích và cổng đích. Điều đó có nghĩa là giới hạn cổng ± 64k thực sự CHỈ cho một khách hàng. Về mặt lý thuyết, máy chủ có thể có bất kỳ số lượng kết nối mở nào, CHỈ bị giới hạn bởi phần cứng của nó.
Rizon

@Rizon, đó là sự thật. Tôi đã cập nhật câu trả lời và thay đổi giới hạn cổng mở và thay vào đó đã đề cập đến giới hạn mô tả tệp, đây là giới hạn mà mọi người thường gặp phải đầu tiên.
kanaka

36

Chỉ cần làm rõ: số lượng kết nối máy khách mà máy chủ có thể hỗ trợ không liên quan gì đến các cổng trong kịch bản này, vì máy chủ [thường] chỉ nghe các kết nối WS / WSS trên một cổng duy nhất. Tôi nghĩ những gì các nhà bình luận khác muốn nói đến là mô tả tập tin. Bạn có thể đặt số lượng mô tả tệp tối đa khá cao, nhưng sau đó bạn phải coi chừng kích thước bộ đệm ổ cắm cộng với mỗi ổ cắm TCP / IP đang mở. Dưới đây là một số thông tin bổ sung: /server/48717/prreal-maximum-open-file-descriptors-ulimit-n-for-a-high-volume-system

Đối với độ trễ giảm qua WS so với HTTP, điều đó đúng vì không còn phân tích cú pháp các tiêu đề HTTP ngoài việc bắt tay WS ban đầu. Thêm vào đó, khi càng nhiều gói được gửi thành công, cửa sổ tắc nghẽn TCP sẽ mở rộng, giảm RTT một cách hiệu quả.


AFAIR có một cổng đến, nhưng luôn có một cổng đi được mở cho mỗi kết nối. Đây chỉ là một phần của vấn đề C10k .
Arnaud Bouchez

14

Bất kỳ máy chủ đơn hiện đại nào cũng có thể phục vụ hàng ngàn khách hàng cùng một lúc . Phần mềm máy chủ HTTP của nó đã được định hướng theo hướng Sự kiện (IOCP) (chúng tôi không còn trong một kết nối Apache cũ = một phương trình / luồng xử lý nữa). Ngay cả máy chủ HTTP được tích hợp trong Windows (http.sys) cũng được định hướng IOCP và rất hiệu quả (chạy ở chế độ kernel). Từ quan điểm này, sẽ không có nhiều sự khác biệt về tỷ lệ giữa WebSockets và kết nối HTTP thông thường. Một kết nối TCP / IP sử dụng một ít tài nguyên (ít hơn một luồng) và HĐH hiện đại được tối ưu hóa để xử lý nhiều kết nối đồng thời: WebSockets và HTTP chỉ là các giao thức lớp ứng dụng OSI 7, kế thừa từ thông số kỹ thuật TCP / IP này.

Nhưng, từ thử nghiệm, tôi đã thấy hai vấn đề chính với WebSockets:

  1. Họ không hỗ trợ CDN;
  2. Họ có vấn đề bảo mật tiềm năng.

Vì vậy, tôi muốn giới thiệu như sau, cho bất kỳ dự án:

  • Chỉ sử dụng WebSockets cho thông báo của khách hàng (với cơ chế dự phòng để bỏ phiếu dài - có rất nhiều thư viện xung quanh);
  • Sử dụng RESTful / JSON cho tất cả các dữ liệu khác, sử dụng CDN hoặc proxy cho bộ đệm.

Trong thực tế, các ứng dụng WebSockets đầy đủ không mở rộng tốt. Chỉ cần sử dụng WebSockets cho những gì chúng được thiết kế để: đẩy thông báo từ máy chủ đến máy khách.

Về các vấn đề tiềm ẩn khi sử dụng WebSockets:

1. Cân nhắc sử dụng CDN

Hôm nay (gần 4 năm sau), quy mô web liên quan đến việc sử dụng giao diện người dùng Nội dung Mạng phân phối (CDN), không chỉ cho nội dung tĩnh (html, css, js) mà còn cả dữ liệu ứng dụng (JSON) của bạn .

Tất nhiên, bạn sẽ không đặt tất cả dữ liệu của mình vào bộ đệm CDN, nhưng trên thực tế, rất nhiều nội dung phổ biến sẽ không thay đổi thường xuyên. Tôi nghi ngờ rằng 80% tài nguyên REST của bạn có thể được lưu trữ ... Thậm chí chỉ một phút thời gian hết hạn CDN (hoặc 30 giây) có thể đủ để cung cấp cho máy chủ trung tâm của bạn một hoạt động mới và tăng cường khả năng phản hồi của ứng dụng rất nhiều, vì CDN có thể được điều chỉnh theo địa lý ...

Theo hiểu biết của tôi, chưa có hỗ trợ WebSockets trong CDN và tôi nghi ngờ nó sẽ không bao giờ như vậy. WebSockets là trạng thái đầy đủ, trong khi HTTP là không trạng thái, do đó rất dễ lưu trữ. Trên thực tế, để làm cho WebSockets CDN thân thiện, bạn có thể cần phải chuyển sang cách tiếp cận RESTful không trạng thái ... sẽ không còn là WebSockets nữa.

2. Vấn đề bảo mật

WebSockets có các vấn đề bảo mật tiềm ẩn, đặc biệt là về các cuộc tấn công của DOS. Để minh họa về các lỗ hổng bảo mật mới, hãy xem bộ slide nàyvé webkit này .

WebSockets tránh mọi cơ hội kiểm tra gói ở cấp lớp ứng dụng OSI 7, hiện đang trở thành tiêu chuẩn khá, trong bất kỳ bảo mật kinh doanh nào. Trong thực tế, WebSockets làm cho việc truyền tải bị xáo trộn, do đó có thể là một vi phạm lớn về rò rỉ bảo mật.


2
@ArnaudBouchez - +1 cho giải trình hay trên CDN. Câu hỏi tiếp theo nhanh - bạn nghĩ gì về tính khả thi của mạng phân phối Sự kiện? Được tạo mẫu theo CDN nhưng hướng đến việc cung cấp dữ liệu phát trực tuyến, v.v. qua websockets hoặc một số công nghệ khác chưa được nhìn thấy.
quixver

8

Hãy nghĩ về nó theo cách này: cái gì rẻ hơn, giữ kết nối mở hoặc mở một kết nối mới cho mọi yêu cầu (với chi phí đàm phán để làm như vậy, hãy nhớ đó là TCP.)

Tất nhiên, nó phụ thuộc vào ứng dụng, nhưng đối với các kết nối thời gian thực dài hạn (ví dụ như trò chuyện AJAX), tốt hơn hết là giữ kết nối mở.

Số lượng kết nối tối đa sẽ được giới hạn bởi số lượng cổng miễn phí tối đa cho các ổ cắm.


Bạn có thể giữ kết nối mở mà không cần sử dụng WebSocket (nhờ tùy chọn giữ nguyên HTTP / 1.1). Tôi không chắc tôi hiểu quan điểm của bạn ở đây.
Arnaud Bouchez

1
+1. Mọi người có xu hướng quên thiết lập kết nối TCP liên quan đến syn / ack / ack và TLS yêu cầu nhiều chuyến đi khứ hồi hơn để trao đổi khóa.
quixver

1
@ArnaudBouchez kiểm tra en.wikipedia.org/wiki/HTTP_persistent_connection#HTTP_1.1 WebSockets được mở miễn là bạn muốn và không bị hack (như bỏ phiếu dài và các lựa chọn thay thế khác).
kaoD

-5

Không, nó không mở rộng quy mô, mang lại công việc to lớn cho các tuyến đường trung gian. Sau đó, ở phía máy chủ, các lỗi trang (bạn phải giữ tất cả các mô tả đó) đang đạt giá trị cao và thời gian để đưa tài nguyên vào vùng làm việc tăng lên. Đây hầu hết là các máy chủ được viết bằng JAVA và có thể nhanh hơn để giữ những ánh mắt đó sau đó để phá hủy / tạo một cái. Khi bạn chạy một máy chủ như vậy trên máy, bất kỳ quá trình nào khác không thể di chuyển được nữa.

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.