Thêm Mô-Đun Máy Chủ HTTP Cho Skynet - nói dối e blog

Thêm Mô-Đun Máy Chủ HTTP Cho Skynet

Việc tích hợp module HTTP server vào hệ sinh thái Skynet từ lâu đã không được ưu tiên, chủ yếu xuất phát từ hai lý do then chốt. Thứ nhất, lĩnh vực xử lý giao thức web không nằm trong chuyên môn của tôi. Thứ hai, cộng đồng phát triển web server đã quá dày đặc với hàng loạt chuyên gia giàu kinh nghiệm, những người chắc chắn sẽ xây dựng giải pháp hiệu quả hơn tôi rất nhiều. Thị trường hiện tại ngập tràn các web server chất lượng cao, điều đó cho thấy ngưỡng phát triển không quá cao. Thêm vào đó, bản thân tôi chưa từng có yêu cầu cụ thể nào cần đến chức năng này, nên quyết định để dành việc triển khai cho đội ngũ có nhu cầu thực tiễn.

Tuy nhiên, tình hình đã thay đổi khi chúng tôi chuẩn bị ra mắt một tựa game mới. Đội ngũ vận hành yêu cầu cung cấp hệ thống web API để phục vụ hoạt động vận hành. Mặc dù có thể dựng riêng một tiến trình phía sau Nginx kết nối với Skynet thông qua giao tiếp IPC, nhưng các lập trình viên trong nhóm phát triển game cho rằng nên giữ mọi thứ đơn giản hơn. Việc lắng nghe cổng port và xử lý giao thức HTTP vốn dĩ không phức tạp, nên quyết định tích hợp trực tiếp vào Skynet là hợp lý.

Trước đó, một số nhà phát triển bên ngoài công ty đã tự xây dựng module HTTP server trên nền tảng Skynet. Tuy nhiên, tôi nhận thấy cần phải tách biệt rõ ràng giữa việc phân tích giao thức HTTP và quản lý socket. Mô hình lý tưởng là một module xử lý phản hồi HTTP thuần túy, không phụ thuộc vào các thành phần khác.

Sau khi khảo sát các thư viện phân tích HTTP bằng Lua trên thị trường không tìm thấy giải pháp phù hợp, tôi dành một đêm để xây dựng phiên bản tối giản. Bằng lợi thế về hỗ trợ coroutine mạnh mẽ của Skynet/Lua, module này được thiết kế hoạt động theo mô hình blocking thay vì callback như Node.js, giúp tối ưu hóa hiệu suất xử lý đa luồng trên các hệ thống đa nhân.

Phiên bản hiện tại của module httpd đã có mặt trên nhánh dev, với quy mô khoảng 200 dòng code tinh gọn. Đáng chú ý là lớp bao bọc (wrapper) cho socket Skynet, nơi biến các lỗi trả về từ hàm read/write thành cơ chế ném ngoại lệ (exception) giúp xử lý lỗi trực quan hơn.

Dựa trên cơ sở này, một web server mẫu đã được xây dựng và tích hợp vào thư mục examples của Skynet. Cụ thể, hệ thống lắng nghe trên một cổng port cố định, đồng thời kích hoạt 20 agent (worker) song song chờ xử lý các yêu cầu HTTP. Các agent này luân phiên tiếp nhận kết nối mới thông qua cơ chế round-robin, sử dụng thư viện httpd để phân tích giao thức và gửi phản hồi tương ứng.

Về khía cạnh an ninh, thư viện đã tích hợp các biện pháp phòng vệ cơ bản: tự động từ chối các yêu cầu HTTP không hợp lệ, giới hạn kích thước HTTP header để ngăn chặn tấn công làm tràn bộ nhớ hoặc tiêu hao CPU. Người dùng cũng có thể thiết lập ngưỡng kích thước tối đa cho phần body của HTTP request (đặc biệt hữu ích khi không cần nhận các file POST dung lượng lớn từ client).

Dù chưa thực hiện các bài test benchmark chi tiết do đây chỉ là giải pháp hậu trường phục vụ vận hành nội bộ (không yêu cầu hiệu năng cao), nhưng phản hồi từ nhóm kỹ sư cho thấy hiệu quả đáng ngạc nhiên. Trên môi trường phát triển với máy tính bàn thông thường (4 nhân CPU), hệ thống có thể xử lý hơn 4,000 yêu cầu mỗi giây. Điều này hoàn toàn phù hợp với kỳ vọng của tôi khi thiết kế Skynet với triết lý tối ưu hiệu năng xử lý đa luồng.

0%