Loại Bỏ Giới Hạn Độ Dài Tin Nhắn Trong Giao Tiếp Cluster RPC Của Skynet
Trong một bài viết trước, tôi đã phân tích vì sao giao thức gói tin của Skynet chỉ sử dụng 2 byte để biểu diễn độ dài gói tin - đó là bởi vì những tin nhắn có kích thước lớn nên được xử lý ở tầng ứng dụng phía trên. Tuy nhiên, thực tế hiện nay cho thấy chúng ta cần nhìn nhận tin nhắn dài như một vấn đề riêng biệt, không thể trộn lẫn với xử lý tin nhắn thông thường (thường ngắn hơn) và không nên “che giấu” sự khác biệt này ở tầng thấp.
Gần đây, yêu cầu thực tế đã xuất hiện. Một dự án mới của chúng tôi cần truyền tải những gói tin có kích thước lớn qua giao tiếp cluster. Lúc đầu, một bạn lập trình viên đã dự định tự mình sửa đổi module cluster của Skynet bằng cách thay đổi độ dài trường độ dài trong giao thức底层. Tôi đã kịp thời ngăn cản và trực tiếp tiến hành sửa đổi theo hướng tối ưu hơn.
Giải pháp tôi thực hiện là bổ sung cơ chế đánh dấu tin nhắn dài ngay ở tầng giao thức cluster phía trên. Thực tế, nhờ có sẵn một byte dành cho thông tin đánh dấu nên việc sửa đổi này không làm thay đổi đáng kể cấu trúc giao thức hiện tại. Khi phát hiện tin nhắn (dù là yêu cầu hay phản hồi) vượt quá ngưỡng kích thước cho phép, hệ thống sẽ tự động chia nhỏ gói tin này thành nhiều phần, đồng thời sử dụng bit đánh dấu để chỉ báo đây chỉ là các đoạn tin nhắn chưa hoàn chỉnh. Về phía máy nhận, các đoạn tin này sẽ được tự động hợp nhất lại thành gói tin hoàn chỉnh.
Ban đầu tôi dự tính không sửa đổi module socket channel - thành phần phụ thuộc của cluster, mà để mỗi gói nhỏ mang theo một session độc lập. Tuy nhiên khi thực hiện đến giữa chừng, tôi nhận ra việc nâng cấp nhẹ module socket channel (mà không làm thay đổi giao diện lập trình hiện có) sẽ mang lại hiệu quả tốt hơn. Đặc biệt, việc này còn tận dụng được tính năng hàng đợi ưu tiên thấp cho socket mà tôi đã phát triển trước đó.
Phiên bản sửa đổi này hiện đã được commit lên một branch độc lập có tên “multipart” trên repository Skynet. Tôi khuyến khích các bạn quan tâm tham gia kiểm tra và góp ý.
Đồng thời, tôi cũng đã cải tiến hai macro nội bộ có ý nghĩa mập mờ trong Skynet, qua đó loại bỏ hoàn toàn giới hạn 16MB trước đây áp dụng cho tin nhắn nội bộ. Sau một loạt kiểm thử thực tế, hệ thống hiện đã đạt được mục tiêu đề ra: Tin nhắn RPC trong giao tiếp cluster hiện hoàn toàn không còn bị giới hạn 64KB như trước. Khi kích thước tin nhắn vượt quá 32KB (ngưỡng hiện tại), hệ thống sẽ tự động chia nhỏ để truyền tải từng phần, cho phép các tin nhắn ngắn hơn chen ngang trong quá trình truyền. Điều này có nghĩa nếu bạn dùng cluster để gửi một tin nhắn khổng lồ hàng chục MB, kênh truyền thông vẫn sẽ duy trì hoạt động bình thường mà không bị nghẽn bởi gói tin lớn.