Tôi đã đọc tài liệu C10K cũng như nhiều tài liệu liên quan về mở rộng quy mô lên máy chủ socket. Tất cả các con đường đều trỏ đến những điều sau:Mô hình phân luồng và chia tỷ lệ cho máy chủ TCP với epoll
Tránh sai lầm cổ điển của "chuỗi cho mỗi kết nối".
Thích epoll hơn chọn.
Tương tự như vậy, cơ chế đồng bộ cũ io trong Unix có thể khó sử dụng.
Máy chủ TCP đơn giản của tôi chỉ lắng nghe kết nối máy khách trên ổ cắm trên cổng chuyên dụng. Khi nhận được kết nối mới, phân tích cú pháp yêu cầu và gửi trả lời lại. Sau đó, đóng cửa ổ cắm một cách duyên dáng.
Tôi nghĩ rằng tôi có một xử lý tốt về cách mở rộng quy mô này lên một chuỗi đơn bằng cách sử dụng epoll. Chỉ cần một vòng lặp gọi epoll_wait cho ổ cắm nghe cũng như cho các kết nối máy khách hiện có. Khi trở về, mã sẽ xử lý mới tạo các kết nối máy khách mới cũng như quản lý trạng thái của các kết nối hiện có tùy thuộc vào ổ cắm nào vừa được báo hiệu. Và có lẽ một số logic để quản lý thời gian chờ kết nối, đóng cửa duyên dáng của ổ cắm và phân bổ nguồn lực hiệu quả cho mỗi kết nối. Dường như đủ đơn giản.
Nhưng điều gì sẽ xảy ra nếu tôi muốn mở rộng quy mô này để tận dụng nhiều chuỗi và nhiều lõi CPU? Ý tưởng cốt lõi lưu ý đến điều này là:
Một chuỗi chuyên dụng để nghe các kết nối đến trên ổ cắm nghe TCP. Sau đó, một tập hợp các luồng N (hoặc nhóm luồng) để xử lý tất cả các kết nối máy khách đồng thời hoạt động. Sau đó phát minh ra một số thread an toàn cách mà trong đó các chủ đề nghe sẽ "gửi" kết nối mới (socket) đến một trong các chủ đề công nhân có sẵn. (ala IOCP trong Windows). Chuỗi công nhân sẽ sử dụng vòng lặp epoll trên tất cả các kết nối mà nó đang xử lý để làm những gì mà phương pháp tiếp cận luồng đơn sẽ làm.
Tôi có đi đúng hướng không? Hoặc có mẫu thiết kế chuẩn để thực hiện máy chủ TCP có epoll trên nhiều chủ đề không?
Đề xuất về cách chuỗi nghe sẽ gửi kết nối mới đến nhóm luồng?
Nếu bạn chọn ngôn ngữ linh hoạt, bạn có thể thử http://vibed.org/ tóm tắt bản chất không đồng bộ của lập trình không đồng bộ để bạn vẫn có thể lập trình theo cách đồng bộ. ví dụ: ubyte [] buf = new ubyte [] (1024); dữ liệu tự động = conn.read (buf); conn.write (dữ liệu); – rmc