Loadbalancing web socket


104

Tôi có một câu hỏi về cách tải các ổ cắm web cân bằng.

Tôi có một máy chủ hỗ trợ các ổ cắm web. Các trình duyệt kết nối với trang web của tôi và mỗi trình duyệt sẽ mở ra một ổ cắm web www.mydomain.com. Bằng cách đó, ứng dụng mạng xã hội của tôi có thể đẩy tin nhắn đến khách hàng.

Theo truyền thống, chỉ sử dụng các yêu cầu HTTP, tôi sẽ mở rộng quy mô bằng cách thêm máy chủ thứ hai và bộ cân bằng tải trước hai máy chủ web.

Với ổ cắm web, kết nối phải trực tiếp với máy chủ web, không phải bộ cân bằng tải, bởi vì nếu một máy có giới hạn vật lý là 64 nghìn cổng mở và các máy khách đang kết nối với bộ cân bằng tải, thì tôi không thể hỗ trợ hơn 64k người dùng đồng thời.

Vậy làm cách nào để -

  1. yêu cầu máy khách kết nối trực tiếp với máy chủ web (thay vì trình cân bằng tải) khi tải trang? Tôi có chỉ tải JavaScript từ một nút và trình cân bằng tải (hoặc bất cứ thứ gì) sửa đổi ngẫu nhiên URL cho tập lệnh, mỗi khi trang được yêu cầu ban đầu không?

  2. xử lý một sự khởi đầu gợn sóng? Trình duyệt sẽ thông báo rằng kết nối bị đóng khi máy chủ web tắt. Tôi có thể viết mã JavaScript để cố gắng mở lại kết nối, nhưng nút sẽ biến mất trong một thời gian. Vì vậy, tôi đoán tôi sẽ phải quay lại trình cân bằng tải để truy vấn địa chỉ của nút tiếp theo để sử dụng?

  3. Tôi đã thắc mắc về việc bộ cân bằng tải gửi chuyển hướng theo yêu cầu ban đầu, để trình duyệt yêu cầu ban đầu www.mydomain.comvà được chuyển hướng đến www34.mydomain.com. Điều đó hoạt động khá tốt, cho đến khi nút gặp sự cố - và các trang web như Facebook không làm như vậy. Họ làm nó như thế nào?


1
Bạn có thể tải số dư ở lớp mạng, như được đề xuất ở đây
Chris Snow

1
Ngoài ra còn có các phương pháp thay thế như cân bằng tải dựa trên DNS hoặc sử dụng máy chủ điều phối dựa trên http. Tôi đã cố gắng để tóm tắt các cập nhật mới và nhược điểm của từng phương pháp tại deepstream.io/blog/load-balancing-websocket-connections
wolframhempel

@wolframhempel Liên kết đã chết. :-(
Emile Cormier

Câu trả lời:


94

Đặt một bộ cân bằng tải L3 để phân phối các gói IP dựa trên mã nguồn-IP-cổng băm vào trang máy chủ WebSocket của bạn. Vì bộ cân bằng L3 không duy trì trạng thái (sử dụng nguồn-IP-cổng được băm), nó sẽ mở rộng theo tốc độ dây trên phần cứng cấp thấp (giả sử 10GbE). Vì phân phối là xác định (sử dụng nguồn-IP-cổng được băm), nó sẽ hoạt động với TCP (và do đó là WebSocket).

Cũng lưu ý rằng giới hạn cứng 64k chỉ áp dụng cho TCP / IP gửi đi cho một địa chỉ IP (nguồn) nhất định. Nó không áp dụng cho TCP / IP đến. Chúng tôi đã thử nghiệm Autobahn (một máy chủ WebSocket hiệu suất cao) với 200 nghìn kết nối đang hoạt động trên máy ảo 2 lõi, RAM 4GB.

Cũng lưu ý rằng bạn có thể thực hiện cân bằng tải L7 trên đường dẫn HTTP được thông báo trong quá trình bắt tay WebSocket ban đầu. Trong trường hợp đó, bộ cân bằng tải phải duy trì trạng thái (cặp cổng IP nguồn nào sẽ đến nút phụ trợ nào). Tuy nhiên, nó có thể sẽ mở rộng đến hàng triệu kết nối nếu được thiết lập tốt.

Tuyên bố từ chối trách nhiệm: Tôi là tác giả gốc của Autobahn và làm việc cho Tavendo.


Vì vậy, tôi sẽ tải thư viện javascript của mình từ URL của trình cân bằng tải và cung cấp URL của trình cân bằng tải khi tôi tạo ổ cắm web trong javascript - ý bạn là nó trong suốt với trình duyệt? Thật là tuyệt!
John Smith

1
Có, chỉ có 1 URL và tên máy chủ của URL sau phải phân giải cho bộ cân bằng tải của bạn. Máy chủ phụ trợ WebSocket có các IP nội bộ (không phải công khai) và có thể chạy trên các cổng khác với cổng công khai. Cảnh báo duy nhất là bạn có thể cần phải cho máy chủ WebSocket biết tên máy chủ, IP, cổng hiển thị công khai của họ là gì, vì các máy chủ WebSocket tuân thủ sẽ kiểm tra xem URL được cung cấp trong tiêu đề HTTP của bắt tay WS có phù hợp với tên máy / ip / cổng của họ không. đang nghe.
oberstet

Tôi không có nhiều kết nối websocket để cân bằng nhưng tôi có rất nhiều lưu lượng truy cập trong một hoặc nói rằng rất ít kết nối. vì đơn giản, nói một kết nối bây giờ làm thế nào tôi có thể cân bằng các yêu cầu đi qua một kết nối ổ cắm web?
user1870400

Khi tôi tạo nhiều kết nối hơn 5000+ trong java websocket, nó không giải phóng bộ nhớ .... có giải pháp nào không?
Poonam Patel

3

Lưu ý rằng nếu logic máy chủ websocket của bạn chạy trên nodejs với socket.io, bạn có thể yêu cầu socket.io sử dụng kho lưu trữ khóa / giá trị redis được chia sẻ để đồng bộ hóa. Bằng cách này, bạn thậm chí không phải quan tâm đến bộ cân bằng tải, các sự kiện sẽ lan truyền giữa các phiên bản máy chủ.

var io = require('socket.io')(3000);
var redis = require('socket.io-redis'); 
io.adapter(redis({ host: 'localhost', port: 6379 }));

Xem: http://socket.io/docs/using-multiple-nodes/

Nhưng đến một lúc nào đó, tôi đoán redis có thể trở thành nút cổ chai ...


2

Bạn cũng có thể đạt được cân bằng tải lớp 7 với kiểm tra và "chức năng định tuyến"

Xem "Cách kiểm tra và cân bằng tải lưu lượng truy cập WebSockets bằng Trình quản lý lưu lượng truy cập Stingray và khi cần thiết, cách quản lý lưu lượng truy cập WebSockets và HTTP nhận được trên cùng một địa chỉ IP và cổng." https://splash.riverbed.com/docs/DOC-1451


2
Tôi đã phải thực hiện một số thao tác để tìm thông tin bạn đã liên kết. Máy quay lui đã giúp tôi tìm thấy bản sao trực tiếp của bài viết đó: community.pulsesecure.net/t5/Pulse-Secure-vADC/…
Wyck
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.