2010-03-17 33 views
5

Tôi viết một SocketServer đa luồng đơn giản và tôi tự hỏi như thế nào tốt nhất để xử lý các kết nối đến:Java socketserver: Làm thế nào để xử lý nhiều kết nối đến?

  1. tạo một chủ đề mới cho mỗi kết nối mới. Số lượng đề đồng thời sẽ kết nối hạn chế và chờ đợi giới hạn bằng cách xác định một tồn đọng

  2. thêm tất cả các kết nối đến vào một hàng đợi và có một hồ bơi của đề người lao động mà xử lý hàng đợi

Tôi có khuynh hướng đi cho tùy chọn 2 bởi vì tôi thực sự không muốn từ chối bất kỳ kết nối nào, ngay cả dưới tải trọng cao, nhưng tôi tự hỏi nếu có bất kỳ cân nhắc nào, tôi nên biết về việc chấp nhận các kết nối không giới hạn hiệu quả?

Trả lời

6

Với kết nối không giới hạn, bạn có khả năng có thể tạo một số lượng lớn các chuỗi. Điều đó có nghĩa là cần nhiều xử lý, cộng với mỗi luồng sẽ tiêu thụ một lượng bộ nhớ cố định theo mặc định chỉ dành cho heap (tôi nghĩ con số này là 512kB cho mỗi chủ đề, nhưng điều đó có thể phụ thuộc vào nền tảng).

Bằng cách gộp số lượng chủ đề cố định và chấp nhận số lượng khách hàng hạn chế, bạn sẽ đảm bảo rằng một số khách hàng của bạn sẽ được phục vụ trong một khoảng thời gian hợp lý và máy chủ của bạn sẽ không bị quá tải.

Bạn có thể muốn xem this article on building servers using NIO hoặc có thể xem các khuôn khổ như Apache Mina.

+0

như một (kích thước tôi giả cố định) bơi thread đang được sử dụng số lượng các chủ đề sẽ không được không giới hạn và thay vào đó bị ràng buộc bởi kích thước của hồ bơi. – objects

+0

Xin lỗi - nghĩ rằng tôi đã nhầm lẫn vấn đề bằng cách viết 'bỏ phiếu', không phải 'gộp chung' –

+0

thats ok, cảm ơn vì đã làm rõ – objects

2

Nếu bạn chấp nhận kết nối không giới hạn và quá trình xử lý không đủ nhanh để xử lý luồng kết nối đến, hàng đợi của bạn sẽ lấp đầy - cho đến khi đạt đến một điểm. hầu hết các yêu cầu thậm chí sẽ không còn quan tâm đến câu trả lời nữa, ngay khi bạn nhận được chúng.

+0

Hoặc bạn sẽ hết bộ nhớ. – user359996

2

1 Chủ đề cho mỗi kết nối không mở rộng. Đọc về nó tại vấn đề C10K. Nó được đọc rất lâu, nhưng rất nổi tiếng.

Tôi khuyên bạn nên tìm hiểu về NIO hoặc sử dụng khung công tác ấn tượng netty để xử lý tất cả việc nâng hạng nặng (NIO) cho bạn.

4

tôi thực sự không muốn từ chối bất kỳ kết nối

Trên thực tế bạn có thể làm. Khi bạn bị quá tải, bạn muốn giữ lại đủ dung lượng để loại bỏ tải trọng hiện tại trước khi bạn chấp nhận nữa. Làm chậm mọi người để dừng lại không phải là chấp nhận được nhiều hơn là từ chối kết nối.

Lý thuyết xếp hàng cho biết điểm ngọt là khoảng 70% sử dụng. Nếu máy chủ của bạn sẽ có một tải ổn định cao hơn mà có được phần cứng nhanh hơn cho đến khi nó không.

Có nói rằng, nếu bạn đang mong đợi hàng trăm nghìn kết nối tôi sẽ sử dụng một hồ bơi thread hoặc NIO. Nếu bạn chỉ mong đợi hàng ngàn, một sợi cho mỗi kết nối là cách dễ nhất để đi.

0

tôi thực sự không muốn từ chối bất kỳ kết nối, ngay cả dưới tải cao

lựa chọn của bạn 2 là cách duy nhất để đi theo ý kiến ​​của tôi. Bạn nên có một chuỗi bộ chọn NIO được ghim cho mỗi kết nối 5-10k. Nhưng không có gì có thể trì hoãn chủ đề quan trọng này, vì vậy bạn sử dụng một DEMUX để phân phối công việc trong một số cố định của các chủ đề được ghim và không cho một nhóm luồng. Và một MUX để thu thập công việc và trả lời lại cho khách hàng. Như EJP đã nói, nếu chuỗi công việc của bạn bị trễ, cuối cùng bạn sẽ phải ngắt kết nối trừ khi bạn bắt đầu đổ các thông điệp vào đĩa để làm cho hàng đợi của bạn càng lớn càng tốt. Bằng cách đó, y sẽ không bỏ bất kỳ kết nối nào, ngay cả khi tải cao. Bạn có thể kiểm tra this article mà giải thích điều này một cách chi tiết và sơ đồ dưới đây:

enter image description here

Disclaimer: Tôi là một trong các nhà phát triển của CoralQueue

Các vấn đề liên quan