Giải Pháp Bảo Vệ Quá Tải Cho Dịch Vụ Skynet - nói dối e blog

Giải Pháp Bảo Vệ Quá Tải Cho Dịch Vụ Skynet

Trong tuần vừa qua, tựa game mới nhất của chúng tôi - “Tân Thiên Trận Đồ” đã chính thức ra mắt trên nền tảng Tencent. Tuy nhiên, sự bùng nổ lượng người chơi đột ngột đã khiến một số lỗi kỹ thuật nghiêm trọng được phơi bày. Điều đáng tiếc là các lỗi này đều xuất phát từ việc một số lập trình viên mới gia nhập dự án đã phải vội vã hoàn thành tiến độ trong tuần cuối cùng phát triển. Những đoạn code xử lý yêu cầu quan trọng đã sử dụng các thuật toán có độ phức tạp tính toán O(n) trở lên - thứ không phù hợp với các dịch vụ cần xử lý song song nhiều yêu cầu thời gian thực.

Vấn đề nằm ở chỗ những xử lý tốn kém tài nguyên này lại được tích hợp vào hệ thống xác thực người chơi. Khi xảy ra nghẽn cổ chai, toàn bộ quá trình đăng nhập người dùng bị ảnh hưởng nghiêm trọng. Dù việc sửa lỗi chỉ đơn thuần là tách biệt luồng xử lý và áp dụng các thuật toán tối ưu hơn với độ phức tạp O(logN) hoặc O(1), nhưng cách hệ thống Skynet phản ứng khi xảy ra sự cố lại mang đến nhiều bài học đáng giá.

Cơ chế xử lý song song của Skynet

Theo thiết kế ban đầu, Skynet được xây dựng như một hệ điều hành thu nhỏ với mỗi dịch vụ tương ứng một tiến trình độc lập. Điều này lý tưởng cho việc xử lý song song trên phần cứng đa lõi - số nhân càng nhiều, hiệu suất càng cao. Trong sự cố vừa qua, cơ chế phân tách tiến trình đã chứng minh hiệu quả khi phần xử lý đăng nhập bị nghẽn không ảnh hưởng đến các khu vực游戏副本 (instance) đang vận hành bình thường.

Tuy nhiên, giai đoạn phục hồi sau khi xảy ra quá tải lại không như mong đợi. Khi tốc độ xử lý của một loại yêu cầu chính giảm xuống chỉ còn 20 yêu cầu/giây (xảy ra khi số người chơi trực tuyến vượt quá 8000), toàn bộ hệ thống rơi vào trạng thái “tê liệt nửa phần”. Gần 2 giờ sau, khi lượng người chơi tự giảm xuống còn dưới 4000, hệ thống mới tự phục hồi - một khoảng thời gian dài bất thường khiến trải nghiệm người chơi bị ảnh hưởng nghiêm trọng.

Bàn phím sự cố tuần này

Trong đợt cập nhật dữ liệu mới nhất, một sự cố tương tự đã tái diễn do lỗi cấu hình dẫn đến tập trung 100.000 người chơi trên cùng cụm máy chủ. Điều này khiến dịch vụ tạo nhân vật và xác thực đăng nhập bị nghẽn hoàn toàn. Dù người chơi kiên nhẫn có thể vào game sau 10 phút chờ đợi, nhưng hệ thống vẫn cần vài giờ để phục hồi hoàn toàn. Sau cùng, một lỗi code ẩn giấu khác đã được xác định là thủ phạm chính gây ra hiệu ứng “tuyết lở” này.

Cơ chế domino trong quá tải hệ thống

Điểm mấu chốt nằm ở dịch vụ D - thành phần xử lý dữ liệu trung tâm kết nối với các đại lý người chơi (agent). Mỗi người chơi đều có một agent duy trì trạng thái, trong khi D chỉ đảm nhiệm vai trò xử lý yêu cầu. Khi xảy ra quá tải, mỗi yêu cầu cần thời gian xử lý dài hơn bình thường. Điều này dẫn đến tình trạng nghẽn dây chuyền:

  • Người chơi mất kiên nhẫn liên tục ngắt kết nối và thử lại
  • Dịch vụ D không phân biệt được trạng thái kết nối thực tế
  • Hàng đợi xử lý bị ngập trong hàng ngàn yêu cầu “ma” (từ người chơi đã rời đi)
  • Kết quả xử lý chỉ được trả về khi không ai còn quan tâm, gây lãng phí tài nguyên

Ẩn dụ nhà hàng đầy ắp thực khách

Hãy tưởng tượng một nhà hàng sang trọng với lượng đầu bếp có hạn. Khi khách hàng ùn ùn kéo đến, mỗi bàn đều nhanh chóng gửi yêu cầu nấu ăn. Tuy nhiên, cứ mỗi món ăn cầu kỳ cần thời gian chuẩn bị lâu, lại có thêm hàng chục thực khách mới đến chờ đợi. Những người mất kiên nhẫn rời đi, nhưng đầu bếp vẫn tiếp tục nấu những món đã được đặt. Khi món ăn hoàn thành, bàn ăn đã trống, thức ăn phải đổ bỏ. Những thực khách quay lại buộc phải đặt đơn mới, trong khi bếp vẫn đang bận rộn với những yêu cầu từ quá khứ.

Giải pháp “cảnh báo bận” thông minh

Để phá vỡ vòng lặp tử thần này, chúng tôi đề xuất cơ chế như sau:

  1. Thêm cờ trạng thái bận trong giao thức phản hồi - Mỗi dịch vụ cần có khả năng trả về trạng thái “bận” khi hàng đợi xử lý vượt ngưỡng an toàn
  2. Kiểm soát hàng đợi thông minh - Sử dụng hàm skynet.mqlen để đo chiều dài hàng đợi, kết hợp cơ chế duy trì trạng thái bận qua vài yêu cầu liên tiếp nhằm giảm tải kiểm tra
  3. Vòng lặp retry thông minh - Bên gửi yêu cầu cần xử lý phản hồi “bận” bằng cách tự động lặp lại yêu cầu sau khoảng thời gian chờ thích hợp

Giải pháp lâu dài

Mặc dù cơ chế trên giúp giảm thiểu lãng phí, nhưng việc nâng cấp năng lực xử lý vẫn là ưu tiên hàng đầu:

  • Tối ưu hóa thuật toán xử lý
  • Phân tán dịch vụ nóng theo logic nghiệp vụ hoặc ID người chơi
  • Thiết lập hệ thống giám sát quá tải toàn diện:
    • Ghi nhật ký khi hàng đợi tin nhắn vượt 1024
    • Theo dõi sự gia tăng của coroutine pool
    • Sử dụng module profile đo lường thời gian xử lý từng yêu cầu

Bài học kinh nghiệm

Các kỹ sư mới làm quen với Skynet đều từng vấp phải lỗi này - đó là quy luật tất yếu. Hiện tại, chúng tôi đang phát triển nhánh dev với các tính năng cảnh báo quá tải tích hợp sẵn. Trong tương lai gần, hy vọng hệ thống sẽ tự động điều chỉnh ngưỡng xử lý dựa trên tải thực tế, thay vì phụ thuộc hoàn toàn vào cấu hình thủ công.

0%