Thiết Kế Máy Chủ Game Đa Tiến Trình - nói dối e blog

Thiết Kế Máy Chủ Game Đa Tiến Trình

Hiện tại, hệ thống máy chủ game của chúng tôi được xây dựng theo mô hình đa tiến trình. Việc nhấn mạnh vào “đa tiến trình” là để làm nổi bật một điểm quan trọng khác: mỗi tiến trình đơn luồng. Điều này giúp chúng tôi tập trung giải quyết bài toán trao đổi dữ liệu giữa các tiến trình mà không cần lo lắng về vấn đề khóa dữ liệu giữa các luồng (thread lock).

Khi số lượng tiến trình tăng lên, nếu không có giới hạn trong giao tiếp giữa các tiến trình, hệ thống sẽ trở nên phức tạp và khó kiểm soát. Sau khi phân tích kỹ lưỡng, chúng tôi đã áp dụng các nguyên tắc thiết kế sau:

  1. Vai trò phân tách trong tiến trình giao tiếp hai chiều
    Những tiến trình cần giao tiếp hai chiều với nhiều máy chủ khác sẽ không xử lý logic phức tạp. Thay vào đó, chúng chỉ đóng vai trò lọc và chuyển tiếp dữ liệu. Ví dụ: Tiến trình S nhận dữ liệu từ tiến trình A và chuyển sang B, hoặc ngược lại. Dữ liệu từ một nguồn duy nhất có thể được phân tích giao thức đơn giản rồi phân phối đến nhiều đích khác nhau. Một trường hợp cụ thể là tách dữ liệu chat từ gói tin client gửi đến và chuyển đến tiến trình xử lý chat chuyên dụng.

  2. Luồng dữ liệu một chiều cho tiến trình xử lý logic
    Các tiến trình có xử lý logic phải đảm bảo luồng dữ liệu một chiều. Dù có thể nhận dữ liệu từ nhiều nguồn, kết quả xử lý phải được phản hồi đến một đích duy nhất mà không cần tương tác ngược lại với nguồn dữ liệu ban đầu.

  3. Giới hạn điểm vào/ra trên mỗi tiến trình
    Mỗi tiến trình nên có tối đa một điểm đầu vào hoặc một điểm đầu ra để đơn giản hóa luồng dữ liệu và giảm độ phức tạp.

  4. Tách biệt thao tác tốn thời gian
    Tất cả các thao tác yêu cầu nhiều tài nguyên tính toán hoặc thời gian xử lý dài (như truy vấn cơ sở dữ liệu, xử lý hình ảnh) sẽ được chuyển sang tiến trình riêng biệt và xử lý theo cơ chế hàng đợi.

  5. Phân chia tiến trình theo chức năng và ngữ cảnh
    Mỗi dịch vụ hoặc kịch bản (scenario) sẽ được xử lý bởi một tiến trình độc lập, không chia nhỏ thêm để cân bằng tải. Điều này giúp tối ưu hóa việc quản lý tài nguyên và giảm độ phức tạp trong giao tiếp nội bộ.


Tối ưu hiệu năng thông qua kiến trúc đa tiến trình

Để tận dụng tối đa lợi thế của CPU đa nhân, chúng tôi phân loại tiến trình thành hai nhóm chính:

  • Tiến trình xử lý lưu lượng lớn, tính toán nhẹ: Ví dụ như xử lý gói tin mạng, chuyển tiếp dữ liệu.
  • Tiến trình xử lý lưu lượng nhỏ, tính toán nặng: Ví dụ như logic trò chơi phức tạp, AI.

Ưu điểm của mô hình đơn luồng đa tiến trình nằm ở việc loại bỏ hoàn toàn cơ chế khóa (lock-free), cho phép mỗi tiến trình hoạt động với hiệu suất tối đa. Dù việc sao chép dữ liệu giữa các tiến trình có tạo ra gánh nặng, nhưng trong hệ thống game với logic phức tạp, chi phí này thường không phải là điểm nghẽn (bottleneck).

Ví dụ minh họa:
Xét phép tính a/b + c/d + e/f:

  • Đa luồng: Dùng 3 luồng song song tính 3 phân số. Tuy nhanh nhưng tăng độ phức tạp đồng bộ hóa.
  • Đa tiến trình: Tạo chuỗi 3 tiến trình, mỗi tiến trình tính một phân số và truyền kết quả. Dù có chi phí giao tiếp, nhưng khi xử lý hàng loạt phép tính, hiệu suất tổng thể cao hơn nhờ tính song song thực sự giữa các nhân CPU.

Để tăng thông lượng (throughput), chúng tôi chia nhỏ tác vụ xử lý gói tin thành các giai đoạn (pipeline) và xử lý song song qua nhiều tiến trình. Đồng thời, tất cả thao tác tốn thời gian (như truy vấn cơ sở dữ liệu) đều được chuyển sang tiến trình riêng biệt để xử lý bất đồng bộ.


Quản lý cảnh (scene) và dịch vụ vị trí

Khi người chơi kết nối, toàn bộ gói tin sẽ đi qua dịch vụ vị trí (Location Service) - tiến trình có vai trò:

  • Xác định vị trí hiện tại của người chơi.
  • Phân phối dữ liệu đến tiến trình cảnh tương ứng.
  • Quản lý việc phát tán tin nhắn giữa người chơi (broadcast).

Quy trình chuyển cảnh:

  1. Khi người chơi chuyển cảnh, máy chủ cảnh hiện tại gửi dữ liệu người chơi đến dịch vụ dữ liệu (Data Service).
  2. Data Service lưu dữ liệu vào cơ sở dữ liệu và cập nhật cache.
  3. Location Service nhận mã cảnh mới và chuyển tiếp gói tin người chơi đến máy chủ cảnh đích.

Quản lý vật phẩm và tài nguyên:

  • Các tiến trình cảnh gửi yêu cầu tạo vật phẩm mới đến dịch vụ phân bổ vật phẩm (Item Distribution Service).
  • Dịch vụ này sinh ra vật phẩm và thông báo Location Service để cập nhật vị trí xuất hiện.

Lợi ích của thiết kế này:

  • Mỗi máy chủ cảnh chỉ có một nguồn dữ liệu duy nhất (Location Service).
  • Không phụ thuộc vào cơ sở dữ liệu hoặc đồng hồ hệ thống, giúp việc gỡ lỗi trở nên đơn giản và trực quan hơn.

Giải quyết bài toán khởi động hệ thống

Khi số lượng tiến trình tăng lên, vấn đề nan giải đầu tiên là khởi động và định vị dịch vụ. Việc cấu hình địa chỉ tiến trình thủ công hoặc dùng tên miền phụ trong phát triển đều không khả thi. Giải pháp chúng tôi áp dụng là xây dựng một máy chủ tên (Name Server) với các tính năng:

  • Đăng ký và định vị động các tiến trình.
  • Theo dõi trạng thái hoạt động của từng dịch vụ.
  • Giao thức dựa trên văn bản (tương tự POP3) để dễ dàng kiểm tra bằng công cụ telnet.

Ví dụ:
Khi một tiến trình mới khởi động, nó tự động đăng ký với Name Server bằng lệnh REGISTER game_logic_01 192.168.1.10:5000. Các tiến trình khác có thể truy vấn địa chỉ của game_logic_01 bằng lệnh LOOKUP game_logic_01.

Giải pháp này không chỉ giúp hệ thống linh hoạt khi mở rộng mà còn tạo điều kiện thuận lợi cho đội ngũ vận hành trong việc giám sát và bảo trì.


0%