Sách trắng lag game
Tiếng Việt

Sách trắng
lag game

Sách trắng này giải thích nguyên nhân khiến màn hình giật khựng, nhân vật dịch chuyển tức thời hoặc mất kết nối, chia thành 13 tầng từ màn hình game của bạn đến cơ sở dữ liệu của server. Mỗi nguyên nhân đều ghi rõ cách xác nhận và đội phụ trách. Bạn có thể thay đổi điều kiện trong các thí nghiệm để kiểm tra. Các ví dụ chủ yếu lấy từ MMO, nhưng phần lớn nội dung áp dụng cho game online nói chung, bất kể thể loại.

00Bắt đầu

Bốn yếu tố gây ra lag

Nguyên nhân thì có hơn một trăm, nhưng các yếu tố tạo ra lag gom lại được thành bốn nhóm lớn: gói tin đến muộn, đến lúc nhanh lúc chậm, hoàn toàn không đến, hoặc có nơi ngừng tính toán. Game dùng nhiều kỹ thuật để che các yếu tố này, và dấu vết lộ ra khi che không nổi chính là “hình dạng” của lag mà chúng ta nhìn thấy.

Trong MMO, thế giới bạn thấy trên màn hình là hình được vẽ lại từ các gói tin server gửi về. Mỗi game một khác, nhưng thường server tính trạng thái game 10–30 lần trong 1 giây (mỗi lần như vậy gọi là một tick), rồi chỉ chọn ra những thay đổi quanh từng người chơi để gửi đi thành gói tin. PC của bạn đọc các gói tin nhận được và vẽ màn hình. Vì vậy, phần lớn lag là chuyện game thể hiện ra sao khi “gói tin không đến đúng lúc”.

Cũng có những trường hợp nằm ngoài bốn yếu tố này. Khi server và PC của bạn tính cùng một việc theo hai cách khác nhau (khác quy tắc di chuyển, lỗi code), hiện tượng kéo ngược hoặc không hiển thị vẫn xảy ra dù đường truyền hoàn toàn bình thường. Manh mối của loại lag này là nó lặp lại ở cùng một địa điểm hoặc cùng một thao tác, bất kể ping.

Từ yếu tố đến triệu chứng

So sánh

Hãy nghĩ tới chuyện giao hàng. Hàng lúc nào cũng mất 3 ngày mới tới là độ trễ; kiện thì một ngày, kiện thì năm ngày là jitter; thùng hàng bị thất lạc là mất gói; kho trung chuyển đóng cửa là ngưng trệ. Game xoay xở bằng những cách như “thùng đến muộn hoặc không đến thì đoán dựa vào thùng trước và thùng sau để lấp vào (nội suy, ngoại suy)” hay “không đến thì yêu cầu gửi lại (truyền lại)”.

Làm quen với thang thời gian

Chuyện lag phần lớn tính bằng mili giây (ms, 1/1000 giây). Chỉ cần nhớ vài con số trong bảng dưới đây, bạn sẽ hiểu những gì đội phát triển game và đội hạ tầng nói dễ hơn nhiều.

MốcThời gianÝ nghĩa

Đặc tính chung của hàng đợi ở mọi tầng

CPU, ổ đĩa, cơ sở dữ liệu, router, đường truyền của nhà mạng. Tầng khác nhau nhưng cấu trúc thì giống nhau: có các worker xử lý yêu cầu (core CPU, thread, kết nối DB, v.v.), và phía trước chúng hình thành một hàng đợi. Khi worker rảnh, hàng đợi trống; nhưng khi mức độ bận (mức sử dụng) vượt 80–90%, hàng đợi dài ra rất nhanh. Với một worker và yêu cầu đến ngẫu nhiên, thời gian chờ trung bình bằng đúng thời gian xử lý khi mức sử dụng là 50%, gấp 4 lần khi ở 80% và gấp 9 lần khi ở 90%. Đây là câu trả lời cho câu hỏi “CPU vẫn còn dư 10%, sao lại lag?”. Thêm nữa, con số CPU trên màn hình giám sát thường là trung bình của nhiều core trong 1–5 phút, nên nó che mất tình huống chỉ một core chạm 100% hay những khoảnh khắc tải dồn về chỉ trong vài giây.

Sách trắng này đề cập gì và không đề cập gì

Sách trắng này bàn về các nguyên nhân gây lag trong lúc chơi game online, từ PC hay điện thoại vẽ màn hình game của bạn, qua mạng gia đình, nhà mạng, trung tâm dữ liệu, đến server và cơ sở dữ liệu. Cloud gaming (nhận màn hình game dưới dạng video), chat thoại (chạy thành một dịch vụ riêng) và tốc độ tải bản cập nhật hay tải game có cấu trúc khác nên không nằm trong phạm vi sách. Tuy vậy, các nguyên nhân về mạng bên trong chúng (Wi-Fi, bufferbloat, đường truyền bị nghẽn, v.v.) giống với các nguyên nhân được nêu ở đây.

01Toàn cảnh

Hành trình của gói tin: từ thao tác của người chơi đến DB của server

Khi bạn bấm nút skill, tín hiệu đi qua PC của bạn, mạng gia đình, nhà mạng và trung tâm dữ liệu rồi mới tới server. Kết quả, sau khi được nhiều tầng bên trong server xử lý, lại đi ngược qua đúng các tầng đó và được vẽ lên màn hình. Tổng cộng có 13 tầng, và tầng nào bị tắc cũng gây ra lag. Bấm vào một tầng trên bản đồ dưới đây để chuyển tới chương tương ứng.

02Tự tay thử

Phòng thí nghiệm lag

Đây là một mô phỏng nhỏ gồm một server, một đường truyền và một PC. Hãy lần lượt làm hỏng từng điều kiện để xem giật khựng, dịch chuyển tức thời, kéo ngược, tua nhanh, quay chậm, trễ thao tác, đứng hình và mất kết nối hình thành ra sao. Dòng thời gian gói tin vẽ mỗi gói thành một đường nối từ lúc gửi đến lúc nhận. Đường càng nghiêng thì gói đi càng lâu, còn dấu × là gói bị mất.

03Tra theo biểu hiện

Từ điển triệu chứng

Người chơi thường chỉ nói “bị lag”, nhưng hình dạng của lag cho biết khá nhiều về nguyên nhân. Hình nhỏ của mỗi triệu chứng là vệt đường mà nhân vật trên màn hình đã đi qua. Các chấm chồng lên nhau nghĩa là nhân vật dừng lại; chấm giãn ra nghĩa là nhân vật nhanh lên hoặc nhảy cóc.

Giật khựng

Chuyển động không mượt, cứ khựng lại một chút rồi chạy tiếp, lặp đi lặp lại. Nếu ping vẫn ổn thì nhiều khả năng do khung hình trên PC của bạn (client, OS); nếu ping lúc cao lúc thấp thì nhiều khả năng là jitter của Wi-Fi hoặc đường truyền. Tuy vậy, chỉ số ping trong game thường được đo bên trong vòng lặp game chạy theo từng khung hình, nên khi frame time vọt lên thì con số ping cũng có thể nhảy theo.

Dịch chuyển tức thời

Nhân vật nhảy thẳng tới một vị trí ở xa mà không thấy quá trình di chuyển. Thường có nghĩa là gói tin bị gián đoạn một lúc. Hãy xem mất gói, đường truyền đứt trong chốc lát, server đứng, ngoại suy sai. Nếu mọi người khác đều ổn mà chỉ một người bị nhảy thì nghi ngờ đường truyền của người đó trước.

Kéo ngược

Nhân vật của bạn đang đi tới thì bị kéo về chỗ vừa đi qua. Màn hình của bạn (dự đoán) và phán định của server không khớp. Có thể input của bạn không tới được server (mất gói), bước kiểm tra di chuyển của server đã cắt bớt quãng đường, hoặc hai bên tính di chuyển khác nhau.

Tua nhanh

Màn hình đang đứng bỗng chạy lại, và mọi chuyển động, đòn đánh, sát thương bị dồn lại trôi qua thật nhanh cùng một lúc. Gói tin bị dồn ứ ở đâu đó rồi được giải phóng cùng lúc. Điển hình là chờ truyền lại TCP, server tính dồn để đuổi kịp, hoặc client xử lý không kịp.

Quay chậm

Mọi thứ chuyển động chậm. Việc tung skill và quái di chuyển trông như bị kéo dài ra. Tùy thiết kế server, tốc độ có thể vẫn giữ nguyên nhưng hiện ra thành giật khựng hoặc dịch chuyển tức thời. Server không kịp xử lý xong mỗi tick đúng hạn. Đường truyền vẫn ổn nên ping đo bên ngoài game không đổi; ping trong game có thể tăng nhẹ nếu có lẫn thời gian chờ xử lý của server. Hãy xem số người tăng đột biến, tính toán tầm nhìn, broadcast, thiếu bộ nhớ.

Trễ thao tác

Từ lúc bấm đến lúc thấy kết quả mất một khoảng thời gian. Bản thân màn hình có thể vẫn mượt. Thời gian khứ hồi (ping) dài, hoặc có hàng đợi bị dồn ở đâu đó. Hãy xem khoảng cách, hàng đợi của router, Nagle (tính năng của TCP gom các gói nhỏ lại rồi mới gửi), hàng đợi của server. Nếu ping thấp mà lúc nào cũng ì thì hãy xem phía PC của bạn như V-Sync hay FPS thấp, hoặc thiết kế bắt mọi hành động phải chờ server xác nhận (chương về cơ chế đồng bộ).

Đứng hình

Mọi thứ trên màn hình dừng lại một lúc (0,5 giây đến vài giây) rồi chạy tiếp. Server đứng toàn bộ (GC, deadlock, gọi đồng bộ), đường truyền đứt trong chốc lát, hoặc PC của bạn bị đứng.

Nuốt thao tác·rollback

Hành động rõ ràng đã làm lại bị coi như chưa từng xảy ra, hoặc kết quả bị đảo ngược một lúc lâu sau. Yêu cầu bị mất (mất gói, tràn hàng đợi), server phán định khác với màn hình của bạn (lệch thời điểm phán định, bị từ chối sau khi đã hiển thị trước), hoặc lưu dữ liệu thất bại giữa chừng (khóa hoặc sự cố DB, server crash).

Mất kết nối

Đang chơi thì kết nối bị ngắt, game quay về màn hình đăng nhập hoặc cửa sổ kết nối lại. Trong suốt thời gian timeout không có gói tin nào. Hãy xem đường truyền đứt lâu, idle timeout, server crash hoặc khởi động lại, server hay PC của bạn đứng lâu hơn timeout (loading lâu). Nếu game tự tắt mà không có thông báo thì hãy xem việc client bị buộc thoát (crash, thiếu bộ nhớ) trước khi xem kết nối.

Không vào được·kẹt loading

Không vào được game, hoặc bị kẹt ở màn hình loading hay màn hình vào game. Các nơi tiếp nhận kết nối mới (hàng đợi kết nối của server, tường lửa, server đăng nhập, DB) đã đầy. Đặc biệt hay gặp ngay sau bảo trì.

Không hiển thị·đối tượng ma

NPC, quái hay người chơi lẽ ra phải có thì chỉ riêng màn hình của bạn không có, hoặc đối tượng đã biến mất vẫn còn trên màn hình của riêng bạn. Tình trạng này thường do thiếu một gói tin hoặc vẽ thất bại, ít liên quan đến tốc độ. Hãy xem khác kênh hoặc khác phasing, mất thông báo xuất hiện hay rời đi, bị hủy trong lúc loading, tải asset thất bại. Manh mối quyết định là khi đi ra khỏi tầm nhìn rồi quay lại thì đối tượng có hiện ra hay không.

04Thiết kế đồng bộ

Cơ chế đồng bộ và cảm giác chơi

Có game ping 150 ms vẫn chơi bình thường, có game ping 60 ms đã thấy ì. Không chỉ game hành động mới như vậy. Nếu cùng một đường truyền, khác biệt này thường đến từ cách client và server thống nhất với nhau “cái gì được quyết định, khi nào, và ai quyết định”, tức là thiết kế đồng bộ. Trong đó có phần là lựa chọn có chủ ý, có phần thực sự là làm sai.

Game mạng nào cũng phải giải cùng một bài toán. Giữa server và PC của bạn luôn có độ lệch thời gian, và một trong hai bên phải quyết định cách xử lý những gì “chưa được chốt”. Có bốn hướng lựa chọn chính.

  • Chờ: không hiển thị gì cho đến khi server chốt. Chính xác, nhưng ping trở thành tốc độ phản hồi.
  • Hiển thị trước, sửa sau: hành động của bạn được hiển thị ngay, nếu kết quả của server khác thì chỉnh lại. Nhanh, nhưng thỉnh thoảng thấy kéo ngược hoặc hành động bị hủy.
  • Hẹn trước: báo kèm một thời điểm trong tương lai, kiểu “1,5 giây nữa sẽ đập xuống”. Nếu phần hoạt ảnh báo trước dài hơn ping thì ping hoàn toàn không lộ ra.
  • Mọi máy cùng tính giống nhau: chỉ trao đổi input, mỗi máy tự tính y hệt nhau (lockstep, rollback). Lượng dữ liệu gửi đi nhỏ, nhưng độ trễ của một người sẽ lan sang tất cả.

Vì vậy, độ nhạy với ping phụ thuộc vào hai câu hỏi nhiều hơn là vào thể loại: một hành động cốt lõi phải chờ bao nhiêu lượt khứ hồi với server, và thời gian luật chơi cho phép có dư dả hơn “ping + thời gian phản xạ của con người” hay không.

Các cơ chế đồng bộ thường gặp

Cơ chếHoạt động thế nàoThường gặp ởBiểu hiện ở ping 150 msĐiểm yếu
Yêu cầu-phản hồi
Hiển thị sau khi server xác nhận
Bấm nút thì hỏi server, có câu trả lời rồi mới hiển thị.Game theo lượt, game thẻ bài, game idle; UI cửa hàng, giao dịch, chế tạo; dùng skill và vật phẩm trong các MMO đời cũMọi hành động bắt đầu trễ khoảng 0,2 giây. Game theo lượt thì gần như không cảm nhận đượcChuỗi hành động liên tiếp, UI có nhiều lượt khứ hồi trên một màn hình
Đồng bộ trạng thái + nội suy
Server có thẩm quyền
Server gửi trạng thái game theo từng tick, client vẽ nối liền giữa hai trạng thái.Hiển thị người chơi khác và quái trong đa số MMONgười khác hiện ra ở trạng thái của khoảng 0,2 giây trước. Bình thường gần như không nhận raJitter (độ dao động của khoảng cách giữa các lần gói tin đến) và mất gói → dịch chuyển tức thời, tick rate thấp
Dự đoán phía client + hiệu chỉnh theo serverInput của bạn được áp dụng ngay, khi kết quả của server về thì so sánh và chỉnh lại.FPS, MMO hành động, di chuyển trong đa số MMOThao tác của bạn phản hồi ngay. Thỉnh thoảng bị kéo ngược một chútNếu client và server tính khác nhau thì phải hiệu chỉnh thường xuyên
Bù trễ
Server quay ngược để phán định
Server quay ngược về thời điểm trong quá khứ mà người tấn công đang nhìn thấy để phán định trúng hay trượt.FPS, game hành động non-targetNgười bắn thấy công bằng, nhưng người bị bắn thì “đã núp rồi mà vẫn trúng”Người bị trúng thấy oan. Ping của người tấn công càng cao thì quay ngược càng xa, càng tệ
Đồng bộ lệnh hoặc đích đếnChỉ gửi ý định như “đi tới đây”, “tấn công mục tiêu này”, rồi hai bên tự tính phần còn lại.MMO click chuột để di chuyển, chiến đấu tab-target, một số MOBAChỉ lúc xuất phát hơi trễ, di chuyển và tấn công vẫn mượtNếu đường đi hoặc kết quả lệch nhau thì cần hiệu chỉnh
Hẹn giờ sự kiện
Dựa trên giờ server
Báo kèm một thời điểm trong tương lai như “bắt đầu lúc giờ server T”, mỗi client tự phát đúng vào thời điểm đó.Pattern của boss raid, cutscene, sự kiện đúng giờNếu báo trước dài hơn ping thì gần như không ảnh hưởngNếu tin đến muộn hơn giờ hẹn thì phần đầu bị bỏ qua
Lockstep tất địnhGom input của mọi người rồi tính y hệt nhau trong cùng một lượt. Input được cộng thêm một độ trễ cố định.RTS (kiểu StarCraft), một số game co-op và giải đốMọi input đều trễ đều (che bằng âm thanh và hiển thị ngay khi bấm). Jitter lớn thì tất cả cùng đứng hìnhJitter, mất gói, người chậm nhất
Rollback
Dự đoán rồi quay ngược
Dự đoán input của đối thủ để chạy trước, đoán sai thì quay ngược về quá khứ và tính lại.Game đối kháng (kiểu GGPO), một số game hành động và thể thaoCảm giác điều khiển gần như tức thì (thường trễ input 1–3 khung hình). Động tác của đối thủ thỉnh thoảng nhảy vài khung hìnhPing lớn thì mỗi lần quay ngược xa hơn, trông như dịch chuyển tức thời
Client có thẩm quyềnMỗi client tự quyết định kết quả của mình, server chỉ chuyển tiếp và ghi lại.Một số game mobile và casual, kiến trúc P2P hoặc relayMàn hình của bạn mượt. Kết quả lệch với màn hình của người khácHack, “tôi bắn trúng rồi mà không tính”

Game thực tế kết hợp các cơ chế này. Thông thường mỗi hành động chọn một cách riêng: di chuyển dùng dự đoán, skill hiển thị trước rồi chốt sau, pattern boss dùng hẹn giờ sự kiện, giao dịch dùng yêu cầu-phản hồi.

Điểm chung của các game vẫn mượt ở ping 150 ms

1. Không có lượt khứ hồi nào chen vào giữa một hành động. Bấm nút là hoạt ảnh, âm thanh và hiệu ứng bắt đầu ngay (hiển thị trước), còn kết quả của server chỉ dùng cho những phần đến muộn cũng không lộ, như con số sát thương.

2. Thời gian luật chơi cho phép dài hơn ping một cách dư dả. Nếu boss báo trước 1–2 giây thì dù gói tin đến trễ khoảng 0,2 giây và phản xạ của người chơi mất 0,25 giây, vẫn đủ thời gian để né. Skill của bạn cũng vậy: nếu skill có thời gian cast (thời gian tung skill), việc server xác nhận sẽ xong trong lúc thanh cast đang chạy, nên thời gian chờ được giấu trong thời gian cast. Đây là lý do lớn nhất khiến MMO tab-target ít nhạy với ping. Ngược lại, cảnh báo ngắn cỡ 0,5 giây thì chỉ cần ping 150 ms là đã khó nhìn thấy mà né kịp (xem thí nghiệm khung phán định bên dưới).

3. Nhận trước các hành động liên tiếp. Nếu có buffer input (hàng đợi skill), tức là vẫn nhận skill tiếp theo dù bạn bấm trước khi hồi chiêu xong, thì giữa các đòn combo không bị chen thêm lượt khứ hồi nào.

4. Hấp thụ jitter. Bộ đệm nội suy và cách phát dựa trên giờ server biến các gói tin lúc “thường 150 ms, thỉnh thoảng 250 ms” thành một dòng đều đặn luôn trễ khoảng 250 ms. Đổi lại việc nhìn lùi về quá khứ thêm một chút, hình ảnh được mượt. Con người quen rất nhanh với độ trễ cố định, nhưng khó quen với sự thất thường. Game làm tốt sẽ tự nới dài hoặc thu ngắn bộ đệm theo mức jitter tăng giảm.

5. Phán định khớp với “những gì bạn thấy”. Né và trúng được phán định theo thời điểm người chơi nhìn thấy (bù trễ), hoặc luật chơi vốn không phụ thuộc vào vị trí (chọn mục tiêu).

6. Độ trễ của một người không bắt người khác phải chờ. Với kiến trúc server có thẩm quyền, ping của bạn tệ thì người khác vẫn bình thường. Với lockstep hoặc kiến trúc host, người chậm nhất quyết định cảm giác chơi của tất cả.

Phân biệt thiết kế có chủ ý và thiết kế sai

Việc game nhạy với ping có khi là do thiết kế có chủ ý, có khi là do làm sai.

Có thể là lựa chọn có chủ ý
  • Khung phán định ngắn: những game mà chính khung phán định ngắn là cái hay, như parry 0,2 giây hay né đúng lúc (just dodge). Việc ping lấy bớt thời gian phản xạ và jitter làm lệch nhịp là không tránh được, nên người ta giảm nhẹ bằng bù trễ hoặc server theo khu vực.
  • Để server chốt nhằm chống gian lận: với những kết quả tuyệt đối không được để bị qua mặt như tiền tệ trong game, vật phẩm, bảng xếp hạng, việc chờ server xác nhận là đúng.
  • Lockstep: đây là kiến trúc thực tế nhất khi cần đồng bộ hàng trăm đơn vị chỉ bằng input. Đổi lại, độ trễ input phải được điều chỉnh theo ping.
  • Công bằng: cũng có game cố ý làm yếu bù trễ để người bị trúng không phải chịu oan vì người khác có ping cao.
Dấu hiệu nhiều khả năng là làm sai
  • Game điều khiển trực tiếp bằng bàn phím hoặc tay cầm, nhưng ngay cả di chuyển và đánh thường cũng chờ server xác nhận. Làm mà không có dự đoán thì ping trở thành cảm giác tay. Kiểu điều khiển ra lệnh như click chuột để di chuyển thì chờ server xác nhận cũng ít lộ hơn, nên các game như MOBA đôi khi cố ý chọn cách này.
  • Một thao tác UI mà có nhiều lượt khứ hồi: mở cửa sổ → nhận danh sách → xác nhận → mua, nếu mỗi bước là một lượt khứ hồi thì với ping 150 ms sẽ mất 0,7–0,8 giây. Có thể gộp chúng lại thành một lần.
  • Ping đường truyền thấp nhưng lúc nào cũng ì đều: hãy nghi ngờ Nagle (hành vi mặc định của TCP gom các gói nhỏ lại rồi mới gửi, tắt bằng TCP_NODELAY), kiểu chờ hai lần khi yêu cầu bị gom đến tick sau rồi kết quả cũng đợi tick kế tiếp mới gửi, hoặc kiến trúc mà mỗi hành động phải đợi lưu DB xong mới phản hồi. V-Sync hay FPS thấp trên PC của bạn cũng cho cảm giác tương tự.
  • Không có hàng đợi skill, “xác nhận xong mới nhận input tiếp”: giữa mỗi đòn combo đều chen một lượt khứ hồi, nên DPS giảm tương ứng với ping.
  • Nhận đến đâu phát đến đó: nếu không có bộ đệm nội suy hay giờ server mà cứ phát hoạt ảnh theo thứ tự nhận được, jitter sẽ biến thẳng thành hoạt ảnh giật khựng.

Các nguyên nhân gây lag trong thiết kế đồng bộ

Chỉ hiển thị sau khi server phản hồi (mô hình yêu cầu-phản hồi) Request-response (no client-side feedback)

Khi bấm nút, không có animation hay âm thanh nào cho đến khi server trả lời. Ping trở thành chính tốc độ phản hồi.

Vì sao: Skill, di chuyển, nhặt đồ chỉ được phát sau khi server xác nhận → Dẫn đến: Từ lúc bấm, không có phản hồi nào trong khoảng thời gian bằng thời gian khứ hồi + thời gian chờ tick → Trên màn hình: Ping 150 ms thì hành động nào cũng chậm mất 0,2 giây

Triệu chứng: Trễ thao tác · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game)

Giao thức nhiều lượt khứ hồi tuần tự (chatty) Chatty protocol / sequential round trips

Nếu một thao tác cần nhiều lượt khứ hồi tới server theo thứ tự, ping bị nhân lên đúng bấy nhiêu lần.

Vì sao: Mở cửa hàng → yêu cầu danh sách → kiểm tra giá → mua → cập nhật túi đồ, mỗi bước là một yêu cầu riêng → Dẫn đến: Phải nhận được trả lời của yêu cầu trước mới gửi yêu cầu tiếp theo → Trên màn hình: Ping 150 ms thì mua một lần mất gần 1 giây. Loading lâu bất thường

Triệu chứng: Trễ thao tác, Không vào được·kẹt loading · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Không có buffer input cho skill No input/spell queue

Nếu phải nhận xác nhận từ server rằng skill trước đã xong mới bấm được skill tiếp theo, mỗi nhịp combo sẽ bị chen thêm một khoảng thời gian khứ hồi.

Vì sao: Chỉ nhận input skill tiếp theo “sau khi skill trước được xác nhận” → Dẫn đến: Giữa các skill luôn có một khoảng trống bằng ping → Trên màn hình: Giữa các đòn combo có khoảng hở, ping càng cao thì DPS càng giảm

Triệu chứng: Trễ thao tác, Nuốt thao tác·rollback · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game)

Khung phán định ngắn bị ping ăn mất Timing window too short for latency + reaction

Nếu thời gian phải phản ứng ngắn như né tránh, parry, đỡ đòn, ping sẽ ăn mất khoảng thời gian đó và tạo ra những đòn không thể né.

Vì sao: Khung phán định ngắn, như cảnh báo đòn đánh của boss 0,5 giây, phán định parry 0,2 giây → Dẫn đến: Thấy cảnh báo muộn (độ trễ chiều xuống + nội suy), input của bạn cũng tới muộn (độ trễ chiều lên + chờ tick) → Trên màn hình: Rõ ràng đã né mà vẫn trúng, parry bị nuốt

Triệu chứng: Nuốt thao tác·rollback, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game), Hạ tầng server (Đội hạ tầng)

Phán định không có bù trễ Server-now hit validation

Nếu server chỉ phán định trúng đích bằng “vị trí hiện tại trên server”, phán định sẽ lệch với những gì bạn thấy trên màn hình.

Vì sao: Đối thủ trên màn hình của bạn đang ở vị trí trong quá khứ khoảng 0,2 giây (khi ping 150 ms, nội suy 100 ms) → Dẫn đến: Server phán định theo vị trí hiện tại nên đối thủ đã không còn ở chỗ bạn ngắm → Trên màn hình: Rõ ràng đã bắn trúng mà vẫn trượt. Phải bắn đón đầu mục tiêu đang di chuyển

Triệu chứng: Nuốt thao tác·rollback · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Bù trễ quá mức Excessive lag compensation

Nếu quay ngược quá xa theo góc nhìn của người tấn công, người bị bắn dù đã nấp vẫn bị trúng.

Vì sao: Server quay ngược rất xa để phán định cho người tấn công có ping cao → Dẫn đến: Trên màn hình của người bị bắn, họ đã vào chỗ nấp → Trên màn hình: “Bị bắn trúng sau tường”, người ping cao được lợi

Triệu chứng: Nuốt thao tác·rollback · Phụ trách chính Phát triển server (Đội phát triển game)

Client có thẩm quyền Client-authoritative results

Nếu mỗi client tự quyết định kết quả của mình, màn hình của bạn mượt mà nhưng kết quả lệch với màn hình người khác và dễ bị hack.

Vì sao: Client quyết định vị trí và việc trúng đích, server chỉ chuyển tiếp → Dẫn đến: Hai người cùng khẳng định mình bắn trúng trước, server không kiểm chứng được → Trên màn hình: Đối thủ dịch chuyển tức thời, đi xuyên tường, “tôi bắn trúng rồi mà không ăn”

Triệu chứng: Dịch chuyển tức thời, Nuốt thao tác·rollback · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Lockstep phải chờ người chơi chậm nhất Lockstep waits for the slowest peer

Trong cấu trúc mọi người cùng tính chung một lượt, chỉ cần input của một người đến muộn là tất cả phải chờ.

Vì sao: Mỗi lượt phải gom đủ input của mọi người chơi mới tính được → Dẫn đến: Input của một người tới muộn do jitter hoặc mất gói → Trên màn hình: Mọi người cùng khựng một lúc, nặng thì hiện cửa sổ “Đang chờ người chơi”

Triệu chứng: Đứng hình, Giật khựng, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Rollback netcode dự đoán sai Rollback misprediction

Game dự đoán input của đối thủ để hiển thị trước, nếu sai thì quay ngược lại và tính lại. Ping càng lớn thì khoảng quay ngược càng lớn.

Vì sao: Đối thủ đổi input (khác với dự đoán) → Dẫn đến: Input thực tới muộn một nửa ping, nên phải quay ngược đúng khoảng đó để tính lại → Trên màn hình: Động tác của đối thủ bỏ qua vài khung hình hoặc đột ngột thay đổi

Triệu chứng: Dịch chuyển tức thời · Phụ trách chính Phát triển client (Đội phát triển game)

Phát ngay khi nhận, không có timestamp Events played on arrival (no timestamps)

Nếu sự kiện từ server không kèm thời điểm xảy ra mà được phát ngay khi nhận, thời điểm hiển thị sẽ lệch lung tung đúng theo jitter của mạng.

Vì sao: Thực thi sự kiện “bắt đầu tấn công”, “phát hiệu ứng” ngay khi nhận → Dẫn đến: Mỗi gói tin có thời gian tới khác nhau nên khoảng cách lúc dài lúc ngắn → Trên màn hình: Chuỗi động tác tấn công lúc nhanh lúc chậm, thời điểm ra pattern của boss mỗi lần một khác

Triệu chứng: Giật khựng, Tua nhanh · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game)

Chờ tick hai lần Double tick quantization

Nếu gom yêu cầu tới tick sau mới xử lý, rồi kết quả lại đợi đến tick sau nữa mới gửi, khoảng cách tick bị cộng vào hai lần.

Vì sao: Yêu cầu nhận được sẽ xử lý ở tick tiếp theo → Dẫn đến: Kết quả xử lý cũng được gom lại gửi ở tick gửi tiếp theo → Trên màn hình: Ping đường truyền thấp mà phản hồi luôn chậm đều khoảng 1,5 lần khoảng cách tick. Server 10 tick thì trung bình 0,15 giây, tệ nhất 0,2 giây

Triệu chứng: Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game)

Server kiểm tra quá chặt Over-strict server validation

Nếu server kiểm tra tốc độ di chuyển, hồi chiêu, tầm đánh quá chặt, cả những input hợp lệ bị dồn lại do jitter cũng bị từ chối.

Vì sao: Tiêu chí chặt như “quãng đường di chuyển được trong một tick”, “dung sai hồi chiêu 0 ms” → Dẫn đến: Jitter làm hai lệnh dồn tới trong cùng một tick thì bị coi là vi phạm quy tắc → Trên màn hình: Kéo ngược, hồi chiêu đã xong mà skill vẫn bị từ chối

Triệu chứng: Kéo ngược, Nuốt thao tác·rollback · Phụ trách chính Phát triển server (Đội phát triển game)

Cấu trúc host (chủ phòng) Listen server / host advantage

Nếu PC của một người chơi đóng vai server, đường truyền và hiệu năng PC của người đó quyết định cảm nhận của tất cả mọi người.

Vì sao: PC của chủ phòng đóng vai server (P2P, listen server) → Dẫn đến: Đường truyền hoặc PC của chủ phòng chậm thì lan sang mọi người, riêng chủ phòng có ping 0 → Trên màn hình: Chỉ chủ phòng được lợi, chủ phòng thoát thì mọi người đứng hình, mất kết nối

Triệu chứng: Giật khựng, Đứng hình, Mất kết nối · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game), Hạ tầng server (Đội hạ tầng)

Server từ chối sau khi đã hiển thị trước Client-side feedback rejected by server

Nếu server không công nhận đòn đánh hay skill đã được hiển thị trước trên màn hình của bạn, kết quả bạn thấy rõ ràng lại bị coi như chưa từng xảy ra.

Vì sao: Phát trước hiệu ứng đòn đánh, động tác skill khi server chưa xác nhận (hiển thị trước) → Dẫn đến: Server tính lại tầm đánh, vị trí mục tiêu, hồi chiêu, tài nguyên rồi từ chối → Trên màn hình: Hiệu ứng máu đã bắn ra mà không có sát thương, chỉ có động tác skill mà không có tác dụng, chỉ có hồi chiêu chạy

Triệu chứng: Nuốt thao tác·rollback, Kéo ngược · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game)

Tính toán đường đi không khớp khi đồng bộ lệnh Command sync with divergent pathing

Nếu hai bên chỉ trao đổi “đi tới đây” còn đường đi thì mỗi bên tự tính, chỉ cần tính lệch một chút là nhân vật hay quái sẽ đi theo đường khác rồi bị kéo về chỗ cũ.

Vì sao: Khi click để di chuyển hoặc khi quái đuổi theo, chỉ gửi điểm đến còn đường đi thì client tự tính riêng → Dẫn đến: Do khác biệt dữ liệu địa hình, va chạm với nhân vật khác, khác thứ tự tính toán mà đi theo đường khác với server → Trên màn hình: Quái đi xuyên tường rồi bị dời đi chỗ khác trong nháy mắt, nhân vật di chuyển theo click đổi hướng như đang trượt

Triệu chứng: Dịch chuyển tức thời, Kéo ngược · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Tần suất gửi snapshot thấp Low snapshot / update rate

Nếu server chỉ gửi bản cập nhật vị trí (snapshot) vài lần trong 1 giây, bộ đệm nội suy phải đặt dài tương ứng, nên bạn thấy các nhân vật khác ở quá khứ xa hơn.

Vì sao: Để tiết kiệm lưu lượng, chỉ gửi bản cập nhật vị trí 5–10 lần trong 1 giây → Dẫn đến: Muốn vẽ mượt thì bộ đệm phải bằng 2 lần khoảng cách gói (200–400 ms), đặt ngắn thì chỉ lỡ một gói là đối tượng khựng lại → Trên màn hình: Thấy đối thủ đổi hướng muộn và lệch với phán định. Bộ đệm ngắn thì giật khựng, khi mất gói thì dịch chuyển tức thời

Triệu chứng: Giật khựng, Dịch chuyển tức thời, Nuốt thao tác·rollback · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

05Phạm vi ảnh hưởng

Khi chỉ một người chậm, khi chỉ một bên bất thường

Trường hợp khó hiểu nhất trong các báo cáo lag là khi chỉ vài người, hoặc chỉ một bên gặp phải. Một người chậm hiện ra trong mắt người khác thế nào, và người đó có kéo cả người khác chậm theo hay không, hoàn toàn phụ thuộc vào cách server xử lý input và cơ chế đồng bộ. Chương này cũng bàn về hiện tượng hai client mở trên cùng một PC mà chỉ một bên không thấy NPC.

Khi chỉ một số người chơi, một số đường truyền bị chậm

Phần lớn MMO ngày nay dùng kiến trúc server có thẩm quyền. Server quyết định mọi kết quả, client vẽ lại kết quả nhận được. Trong kiến trúc này, lag phần lớn chỉ xuất hiện ở người bị chậm.

  • Chính người bị chậm gặp trễ thao tác: các hành động cần server xác nhận như skill hay nhặt đồ bị trễ đúng bằng ping. Di chuyển thì nhờ dự đoán nên hiện ra ngay, nhưng nếu jitter (độ dao động của khoảng cách giữa các lần gói tin đến) lớn thì người đó còn bị kéo ngược và thấy người khác dịch chuyển tức thời.
  • Người khác chỉ thấy nhân vật của người bị chậm khựng lại rồi di chuyển dồn một lượt, hoặc dịch chuyển tức thời. Thao tác của chính họ và chuyển động của quái vẫn bình thường. Nếu chỉ ping cao mà không có jitter và mất gói, nhân vật đó chỉ hiện ở vị trí trễ hơn một chút nhưng vẫn mượt. Thứ khiến một người trông như bị lag trong mắt người khác là jitter và mất gói, nhiều hơn là ping.
  • Nếu chỉ đường truyền của một nhà mạng hoặc khu vực bị kém, những người chơi đó sẽ cùng lúc gặp các triệu chứng trên. Từ phía server, chỉ input của nhóm người đó đến thất thường, nên việc bị bắt nhầm bởi bước kiểm tra di chuyển hay hệ thống phát hiện hack cũng dồn vào họ.
  • Nếu chỉ chậm với một nhân vật nhất định, hãy nghi dữ liệu của nhân vật đó trước khi nghi đường truyền. Nhân vật tích hàng nghìn vật phẩm hay thư phải đọc và ghi nhiều gấp mấy lần người khác mỗi lần vào game và lưu dữ liệu. Có thể phân biệt bằng cách vào cùng nhân vật đó từ PC hoặc đường truyền khác, xem có chậm y như vậy không.

Tuy nhiên, cũng có kiến trúc mà một người chậm làm tất cả cùng chậm. Điểm chung là “có ai đó đang chờ người đó”.

  • Kiến trúc mà mọi người chờ cùng một lượt: lockstep (RTS), nội dung co-op tiến hành theo lượt. Input của một người đến muộn thì tất cả đều dừng. Dù không có jitter, chỉ cần trễ thôi là input của mọi người cũng được áp dụng muộn bằng ping của người chậm nhất.
  • Kiến trúc mà server phải chờ vì đang gửi cho người chậm: gửi kiểu blocking (lệnh gửi dừng lại chờ đến khi bộ đệm gửi có chỗ trống), xử lý đồng bộ. Mọi người do thread server đó phụ trách đều chậm theo. Thông thường, server để cho mỗi người một hàng đợi gửi riêng và không chờ. Khi đó lag chỉ xuất hiện ở người chậm, và nếu hàng đợi quá dài thì chỉ người đó bị mất kết nối.
  • Kiến trúc mà người chậm giữ vai trò trung tâm: P2P (người chơi kết nối trực tiếp với nhau, không qua server) hoặc listen server (PC của người chơi kiêm luôn server) với PC của người đó là host (chủ phòng); sự kiện chỉ tiến hành bằng quyền của đội trưởng tổ đội. Nếu game giao việc tính di chuyển của quái cho client của người chơi ở gần để giảm tải cho server, những con quái do người đó phụ trách sẽ giật khựng trên màn hình của mọi người.
  • Kiến trúc mà phán định quay ngược theo góc nhìn của người chậm: bù trễ. Người chậm bắn trúng một cách công bằng, nhưng người bị trúng thì thấy oan kiểu “đã núp rồi mà vẫn trúng”. Vì vậy game đặt giới hạn cho độ xa quay ngược. Giới hạn này khác nhau tùy game, vào khoảng 0,2–1 giây (giá trị mặc định của Source engine là 1 giây).

Biểu hiện thay đổi theo cách server xử lý input

Cách server xử lý inputNgười chậm gặp gìNgười chậm trong mắt người khácGame của chính người khác
Gom lại xử lý theo tick
Tick cố định, xử lý dồn các input đã nhận
Kết quả skill trễ bằng ping cộng thời gian chờ tick (trễ thao tác). Nếu kiểm tra di chuyển chặt thì bị kéo ngượcKhựng lại rồi đi mấy bước một lúc (tua nhanh, dịch chuyển tức thời). Nếu chỉ ping cao mà không có jitter thì vẫn mượtKhông ảnh hưởng
Xử lý ngay khi đến
Kiểu sự kiện, nhận là áp dụng và gửi đi ngay
Trễ thao tác bằng ping. Chỉ nhanh hơn đúng phần không phải chờ tickDi chuyển lúc nhanh lúc chậm (tua nhanh nhẹ). Nhiều skill đến dồn cùng lúc được thực hiện trong một khoảnh khắcKhông ảnh hưởng
Bộ đệm input cho từng người chơi
Gom riêng cho từng người, mỗi tick lấy một input
Kết quả được chốt trễ bằng độ dài bộ đệmTương đối mượt. Khi bộ đệm cạn thì đứng yên một chútKhông ảnh hưởng
Phán định có bù trễ
Quay ngược về thời điểm người tấn công nhìn thấy
Ngắm đâu trúng đó (trong giới hạn quay ngược)Đã núp rồi mà đòn của người đó vẫn trúngTrúng đòn oan (lan ra)
Lockstep, chờ lượtTrễ thao tác. Input đến muộn thì đứng hìnhTất cả đứng hìnhĐứng hình. Chỉ cần trễ cũng gây trễ thao tác (lan ra mọi người)
Gửi kiểu blocking, xử lý đồng bộ
Server chờ người đó
Đứng hình rồi tua nhanhMọi người do thread server đó phụ trách đều chậmQuay chậm, đứng hình (lan ra những người do thread đó phụ trách)
Người chậm là host
P2P, listen server
Ping của chính người đó bằng 0Màn hình của mọi người đều giật khựngTất cả cùng lag
Người chậm điều khiển quái
Giao việc tính di chuyển của quái cho client
Quái trên màn hình của chính người đó vẫn bình thườngQuái do người đó phụ trách khựng lại rồi dịch chuyển tức thờiMọi người đang đánh những con quái đó (lan ra)

Hai client trên cùng PC, chỉ một bên không thấy NPC

Nếu cùng một người mở hai client trên cùng một PC mà chỉ một bên không thấy NPC, thì nguyên nhân gần như không nằm ở đường truyền. Hai client dùng chung router và chung đường truyền. Khác biệt nằm ở một trong ba chỗ.

  1. Server không gửi cho client đó: khác kênh, instance hoặc phasing của nhiệm vụ (tính năng chia NPC hiển thị theo tiến độ nhiệm vụ); thứ tự đăng ký tầm nhìn bị rối; giới hạn lượng gửi theo từng kết nối; lỗi phiên coi cùng PC, cùng IP là một người; giới hạn chạy nhiều client.
  2. Đã gửi nhưng client bỏ đi: thông báo xuất hiện đến trong lúc loading bị hủy; thông tin xuất hiện dồn về ngay sau khi vào bản đồ bị mất do tràn bộ đệm nhận hoặc do kênh không tin cậy (unreliable, kênh mà gói mất thì không gửi lại); mất snapshot gốc (dữ liệu đầy đủ làm điểm xuất phát khi chỉ gửi phần thay đổi); NPC mới dùng lại ID cũ bị nhầm là NPC cũ; xung đột cổng UDP cố định khiến client kia chặn mất gói; cửa sổ chạy nền bị xử lý chậm nên tràn bộ đệm nhận; ước lượng giờ server bị lệch nên việc hiển thị bị hoãn lại.
  3. Đã nhận nhưng không vẽ được: hai client cùng ghi một file cache một lúc nên tải model thất bại; thiếu bộ nhớ đồ họa (VRAM); khác tùy chọn như giới hạn số người hiển thị; không khớp phiên bản hoặc dữ liệu.

Có ba manh mối mạnh nhất: có bảng tên mà không có model nhân vật không (server đã gửi, vẽ thất bại), ra khỏi tầm nhìn rồi quay lại thì có thấy không (thiếu một thông báo xuất hiện), và đưa cửa sổ bị lỗi lên phía trước thì có đỡ hơn không (giới hạn xử lý của cửa sổ chạy nền). Ngược lại, “đối tượng ma”, chẳng hạn con quái đã chết vẫn đứng trên màn hình của riêng bạn, là do thiếu thông báo rời đi.

Sự cố chỉ một số người gặp

Người chơi chậm di chuyển dồn cục trên màn hình người khác Laggy player seen by others (bursty inputs)

Input của người có đường truyền kém tới server lúc thưa lúc dồn. Nếu server áp dụng đúng số lượng nhận được ở mỗi tick, trong mắt người khác nhân vật đó sẽ khựng lại rồi đi một lúc nhiều bước.

Vì sao: Lệnh di chuyển của người chơi chậm có tick tới 0 lệnh, có tick tới 2–3 lệnh → Dẫn đến: Server áp dụng cùng lúc ở tick nhận được, nên vị trí nhân vật đó thay đổi như bậc thang → Trên màn hình: Trên màn hình người khác, chỉ nhân vật đó khựng lại rồi di chuyển dồn cục một lượt. Những thứ khác vẫn bình thường

Triệu chứng: Tua nhanh, Dịch chuyển tức thời · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Bên ngoài (Bên ngoài)

Tua nhanh do server xử lý ngay khi gói tới Event-driven processing of bursty inputs

Ở server xử lý và thông báo ngay khi gói tin tới, các hành động dồn lại của người chơi chậm sẽ được thực thi liên tiếp ngay lập tức.

Vì sao: Yêu cầu skill, di chuyển của người chơi chậm tới dồn lại → Dẫn đến: Server thực thi theo thứ tự ngay khi nhận và thông báo ngay cho mọi người → Trên màn hình: Trong mắt người khác, người đó dùng nhiều skill trong một khoảnh khắc hoặc di chuyển như tua nhanh

Triệu chứng: Tua nhanh · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Kích thước bộ đệm input theo người chơi Per-player server input buffer (jitter buffer)

Nếu server gom input của mỗi người một chút rồi lấy ra một input mỗi tick, người khác thấy mượt, nhưng thời điểm hành động của chính người đó được xác nhận trên server sẽ muộn đi tương ứng.

Vì sao: Server gom input của người chơi chậm vào bộ đệm và áp dụng một input mỗi tick → Dẫn đến: Bộ đệm nhỏ thì hay bị trống, nhân vật đó đứng yên tại chỗ hoặc server đoán theo input cuối để di chuyển; bộ đệm lớn thì input của chính người đó được xác nhận muộn → Trên màn hình: Nhỏ thì trong mắt người khác bị khựng, lớn thì kết quả skill của chính người đó ra muộn (trễ thao tác)

Triệu chứng: Giật khựng, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Báo nhầm khi kiểm tra, dồn vào người chơi dùng một nhà mạng Anti-cheat / movement validation false positives on bad ISPs

Người chơi dùng đường truyền có jitter lớn có input tới dồn cục, nên hay bị vướng các bước kiểm tra tốc độ và hồi chiêu của server.

Vì sao: Jitter của đường truyền thuộc một nhà mạng hoặc khu vực tăng vào buổi tối → Dẫn đến: Server coi input hợp lệ tới dồn lại là chạy quá tốc độ hoặc vi phạm hồi chiêu → Trên màn hình: Chỉ người chơi dùng nhà mạng đó bị kéo ngược, bị từ chối skill, nặng thì bị server đá ra và mất kết nối

Triệu chứng: Kéo ngược, Nuốt thao tác·rollback, Mất kết nối · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng mạng (Đội hạ tầng)

Một đồng đội chậm và cơ chế boss One laggy member in a synchronized mechanic

Trong cơ chế raid đòi hỏi mọi người cùng phản ứng vào một thời điểm định sẵn, phản ứng muộn của một người chậm sẽ thành thất bại của cả tổ đội.

Vì sao: Cơ chế tập thể như “tất cả cùng tản ra một lúc”, “một người bấm nút” → Dẫn đến: Người chậm thấy cảnh báo muộn, input cũng tới muộn → Trên màn hình: Cả tổ đội bị diệt vì một người đó, các đồng đội khác cảm thấy “tại người bị lag”

Triệu chứng: Nuốt thao tác·rollback, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Quyền điều khiển quái nằm ở client chậm Monster movement delegated to a player client

Có những game giao việc tính di chuyển của quái cho client của một người chơi ở gần để giảm tải server. Nếu đường truyền của người đó kém, con quái đó di chuyển kỳ lạ trên màn hình của mọi người.

Vì sao: Server giao việc tính di chuyển của quái cho client của người chơi gần nhất (hoặc đến trước) → Dẫn đến: Báo cáo kết quả của người được giao tới server muộn hoặc dồn lại → Trên màn hình: Chỉ con quái đó khựng lại rồi dịch chuyển tức thời trên màn hình của mọi người xung quanh. Trên màn hình của chính người được giao thì vẫn bình thường

Triệu chứng: Dịch chuyển tức thời, Giật khựng, Tua nhanh · Phụ trách chính Phát triển server (Đội phát triển game)

Dữ liệu của một nhân vật quá lớn One character with oversized data (inventory, mail, buffs)

Nhân vật tích hàng nghìn vật phẩm, thư, hoặc có danh sách bạn bè, danh sách chặn, buff nhiều bất thường thì lượng dữ liệu phải xử lý khi vào game, khi lưu và khi thông báo cho xung quanh lớn gấp nhiều lần người khác. Chỉ nhân vật đó chậm, bất kể đường truyền.

Vì sao: Nhân vật chơi lâu năm hoặc nhận nhiều phần thưởng sự kiện có tới hàng nghìn món trong túi đồ, hộp thư → Dẫn đến: Mỗi lần vào game, chuyển bản đồ, lưu đều phải đọc và ghi DB tương ứng, thông tin trang bị và buff gửi cho xung quanh cũng lớn → Trên màn hình: Chỉ nhân vật đó loading vào game lâu, khựng khi mở túi đồ hoặc hộp thư. Nếu server chờ lưu trên thread game thì cả những người xung quanh cũng bị đứng hình chốc lát

Triệu chứng: Không vào được·kẹt loading, Trễ thao tác, Đứng hình · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng DB (Đội hạ tầng)

Khác kênh, instance hoặc phasing Different channel / instance / phase

Nếu hai nhân vật ở khác kênh hoặc khác instance, hoặc ở “phasing” khác nhau (NPC hiển thị khác nhau tùy tiến độ nhiệm vụ), hai bên sẽ thấy hai thế giới khác nhau.

Vì sao: Nhân vật thứ hai được xếp vào kênh khác hoặc đang ở bước nhiệm vụ khác → Dẫn đến: Server không gửi NPC đó cho nhân vật này (bình thường) → Trên màn hình: Chỉ một bên không có NPC. Trông như lỗi nhưng đúng theo thiết kế

Triệu chứng: Không hiển thị·đối tượng ma · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Bỏ thông báo xuất hiện tới trong lúc loading Spawn messages dropped before the client is ready

Ngay khi nhân vật vào zone, server gửi thông báo xuất hiện của các NPC xung quanh, nhưng client vẫn đang tải bản đồ nên bỏ thông báo đó đi.

Vì sao: Server gửi thông báo xuất hiện của các đối tượng xung quanh ngay sau khi xử lý vào zone → Dẫn đến: Client đang loading nên chưa có message handler, thông báo bị bỏ → Trên màn hình: Server coi như đã gửi nên không gửi lại. NPC không hiển thị cho đến khi ra khỏi tầm nhìn rồi quay lại

Triệu chứng: Không hiển thị·đối tượng ma · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game)

Thứ tự đăng ký tầm nhìn bị rối Interest-management race on enter/leave

Nếu thời điểm nhân vật được đăng ký vào lưới tầm nhìn trùng với thời điểm NPC chuyển ô lưới, thông báo xuất hiện của NPC đó có thể bị sót.

Vì sao: Việc xử lý vào zone, chuyển kênh, teleport trùng cùng lúc với việc NPC di chuyển → Dẫn đến: NPC đó bị sót khi tính “các đối tượng mới lọt vào tầm nhìn” → Trên màn hình: Chỉ vài NPC cụ thể không hiển thị, hoặc NPC đã rời đi vẫn còn đó

Triệu chứng: Không hiển thị·đối tượng ma · Phụ trách chính Phát triển server (Đội phát triển game)

Mất snapshot gốc (baseline) Lost baseline for delta compression

Với cách server chỉ gửi “những gì khác so với lần trước”, nếu mất thông tin đầy đủ (bản gốc) gửi một lần lúc đầu thì các phần thay đổi sau đó không thể áp dụng được.

Vì sao: Gói thông tin đầy đủ (bản gốc) của đối tượng bị mất hoặc bị bỏ trước khi xử lý → Dẫn đến: Client không có đối tượng để áp dụng các phần thay đổi về sau nên bỏ qua → Trên màn hình: Đối tượng đó không hiển thị, hoặc một lúc lâu sau mới đột ngột xuất hiện

Triệu chứng: Không hiển thị·đối tượng ma, Dịch chuyển tức thời · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Mất thông báo rời đi (đối tượng ma) Missed despawn (ghost entity)

Ngược lại, nếu bỏ lỡ thông báo “đã biến mất”, NPC hoặc người chơi đã chết hay đã rời đi vẫn còn trên màn hình của riêng bạn.

Vì sao: Thông báo chết, rời đi, ra khỏi tầm nhìn bị mất hoặc sai thứ tự → Dẫn đến: Client cho rằng đối tượng đó vẫn còn → Trên màn hình: Quái bị đánh mà không phản ứng, người chơi đã thoát vẫn đứng đó

Triệu chứng: Không hiển thị·đối tượng ma · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Mất thông tin xuất hiện dồn tới ngay sau khi vào Initial spawn burst lost (unreliable channel, receive buffer, fragmentation)

Ngay khi nhân vật bước vào zone, server gửi cùng lúc thông tin xuất hiện của vài chục đến vài trăm đối tượng xung quanh. Nếu gửi chúng qua kênh không tin cậy (unreliable), hoặc bộ đệm nhận bị tràn trong lúc client đang loading nên không đọc socket, một phần sẽ biến mất và không được gửi lại.

Vì sao: Ngay sau khi vào, thông tin xuất hiện dồn tới trong khoảnh khắc ngắn → Dẫn đến: Client đang loading đọc socket muộn nên bộ đệm nhận của OS bị tràn, hoặc gói UDP lớn bị phân mảnh nên chỉ mất một fragment là mất cả gói. Nếu là kênh không tin cậy thì cũng không được gửi lại → Trên màn hình: Chỉ ở client loading chậm hơn mới thiếu vài NPC. Ra khỏi tầm nhìn rồi quay lại thì thấy

Triệu chứng: Không hiển thị·đối tượng ma · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Nhầm lẫn do dùng lại ID đối tượng Entity ID reused without a generation counter

Khi NPC đã chết xuất hiện lại mà server dùng lại cùng ID đối tượng, client đã bỏ lỡ thông báo rời đi trong khoảng đó sẽ nhầm NPC mới là NPC cũ.

Vì sao: NPC chết rồi xuất hiện lại với cùng ID đối tượng → Dẫn đến: Client đã bỏ lỡ thông báo rời đi coi đây là “đối tượng đã biết” nên bỏ qua thông báo xuất hiện, hoặc giữ nguyên trạng thái đã chết → Trên màn hình: NPC không có trên màn hình của một bên, hoặc hiện ở trạng thái đã gục, cũng có khi hiện thành hình dạng của NPC khác

Triệu chứng: Không hiển thị·đối tượng ma · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Xung đột cổng UDP cố định Two clients bound to the same local UDP port

Nếu client được viết để dùng một cổng cục bộ cố định, client thứ hai trên cùng PC sẽ không dùng được cổng đó hoặc phải chia gói tin nhận được với client thứ nhất.

Vì sao: Hai client cùng mở một cổng UDP cục bộ (dùng tùy chọn reuse để ép dùng chung) → Dẫn đến: OS chỉ chuyển gói tin đến cho một socket, hoặc không bảo đảm bên nào nhận. Router và server cũng thấy hai client là cùng một địa chỉ → Trên màn hình: Một bên không nhận được gói tin thế giới nên NPC và người chơi khác không hiển thị, hoặc bị mất kết nối

Triệu chứng: Không hiển thị·đối tượng ma, Mất kết nối, Không vào được·kẹt loading · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game)

Lỗi phân biệt phiên theo IP hoặc thiết bị Session keyed by IP or machine ID

Nếu server hoặc server trung gian phân biệt kết nối bằng IP hay ID thiết bị, hai client trên cùng một PC (cùng IP công cộng) sẽ bị coi là một người.

Vì sao: Bảng phiên được lập theo IP hoặc IP + ID thiết bị → Dẫn đến: Thông tin của client thứ hai ghi đè lên hoặc bị trộn vào phiên thứ nhất → Trên màn hình: Một bên không thấy NPC, bên kia bị mất kết nối hoặc nhận nhầm thông tin của người khác

Triệu chứng: Không hiển thị·đối tượng ma, Mất kết nối · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Giới hạn chạy nhiều client Multi-client restriction policy

Nếu module bảo mật hoặc chính sách server giới hạn nhiều client trên một PC, client thứ hai sẽ bị chặn chạy hoặc chặn kết nối, hoặc client bật trước bị mất kết nối. Một số game chỉ chặn tính năng của client chạy thêm.

Vì sao: Module bảo mật phát hiện chạy trùng, hoặc server giới hạn kết nối thêm từ cùng một thiết bị → Dẫn đến: Từ chối lần chạy hoặc kết nối thứ hai, hoặc ngắt một bên. Hiếm khi chỉ chặn một phần tính năng của client chạy thêm → Trên màn hình: Không vào được hoặc một bên mất kết nối. Ở game chỉ chặn tính năng thì chỉ một bên không thấy NPC, cửa hàng

Triệu chứng: Không vào được·kẹt loading, Không hiển thị·đối tượng ma, Mất kết nối · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game)

Giới hạn xử lý ở cửa sổ chạy nền Background window throttling

Với client ở cửa sổ chạy nền, game, engine và OS đều giảm khung hình và việc xử lý. Gói tin nhận được không được xử lý kịp nên bị dồn lại hoặc tràn.

Vì sao: Giới hạn khung hình khi chạy nền trong tùy chọn game hoặc driver đồ họa (ví dụ driver NVIDIA cho chọn từ 20 đến 200 khung hình mỗi giây), tiết kiệm điện, cấu hình tạm dừng khi chạy nền của engine. OS cũng ưu tiên cấp CPU và GPU cho cửa sổ đang ở phía trước (foreground) → Dẫn đến: Số gói xử lý mỗi khung hình giảm nên hàng đợi dồn lại, bộ đệm nhận tràn thì gói bị bỏ → Trên màn hình: Đưa cửa sổ lên phía trước thì mọi thứ hiện ra dồn một lượt, hoặc một số NPC mãi không hiển thị

Triệu chứng: Không hiển thị·đối tượng ma, Tua nhanh, Mất kết nối · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Bên ngoài (Bên ngoài)

Xung đột khi cùng truy cập file cache hoặc asset Shared cache / asset file lock conflicts

Nếu hai client cùng ghi vào một thư mục cache hoặc khóa file, một bên sẽ không tải được model, texture của NPC.

Vì sao: Hai client cùng lúc ghi file cache, file patch trong cùng một thư mục cài đặt → Dẫn đến: Khóa file thất bại hoặc đọc phải file đang ghi dở nên tải thất bại → Trên màn hình: NPC có bảng tên nhưng không có model nhân vật, hoặc trong suốt

Triệu chứng: Không hiển thị·đối tượng ma · Phụ trách chính Phát triển client (Đội phát triển game)

Streaming thất bại do thiếu bộ nhớ hoặc VRAM Memory / VRAM exhaustion

Khi hai client dùng chung bộ nhớ đồ họa, không còn chỗ để nạp model, texture mới cần dùng nên một phần không được vẽ.

Vì sao: Hai client dùng chung VRAM và RAM. OS cũng có thể giảm hạn mức bộ nhớ đồ họa của cửa sổ chạy nền trước → Dẫn đến: Engine không nạp được model, texture mới hoặc liên tục gỡ ra rồi nạp lại → Trên màn hình: NPC xuất hiện muộn, bị mờ hoặc không hiển thị, giật khựng

Triệu chứng: Không hiển thị·đối tượng ma, Giật khựng · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Bên ngoài (Bên ngoài)

Khác tùy chọn hiển thị Different display settings

Nếu các tùy chọn như giới hạn số người hiển thị, ẩn bảng tên hoặc model NPC, chế độ cấu hình thấp khác nhau giữa hai client, những gì nhìn thấy sẽ khác nhau.

Vì sao: Chỉ một client bật “giới hạn số nhân vật xung quanh được hiển thị” hoặc chế độ cấu hình thấp → Dẫn đến: Không vẽ các NPC ở xa hoặc có mức ưu tiên thấp (bình thường) → Trên màn hình: Chỉ một bên không có NPC

Triệu chứng: Không hiển thị·đối tượng ma · Phụ trách chính Phát triển client (Đội phát triển game)

Phiên bản hoặc dữ liệu client không khớp Client version / data table mismatch

Nếu client thứ hai là bản cài đặt khác hoặc chưa cập nhật xong, nó không biết ID NPC mới mà server gửi nên âm thầm bỏ qua.

Vì sao: Bản cài đặt ở thư mục khác, hoặc client được chạy khi đang cập nhật → Dẫn đến: Nhận ID NPC hoặc ID model không biết thì bỏ qua → Trên màn hình: Chỉ NPC mới thêm không hiển thị ở một bên

Triệu chứng: Không hiển thị·đối tượng ma · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game)

Ngân sách gửi và mức ưu tiên theo kết nối Per-connection bandwidth budget and priority

Nếu server đặt giới hạn lượng gửi cho từng kết nối và gửi những thứ ở gần trước, bên có giới hạn thấp sẽ nhận NPC ở xa muộn hoặc không nhận được.

Vì sao: Ở nơi đông người, server gửi theo thứ tự quan trọng trong giới hạn lượng gửi của từng kết nối → Dẫn đến: Với kết nối có băng thông ước tính thấp (ví dụ bên ở cửa sổ chạy nền nên gửi xác nhận đã nhận muộn), các đối tượng xếp sau cứ bị hoãn mãi → Trên màn hình: NPC ở xa chỉ hiển thị muộn hoặc không hiển thị ở một bên

Triệu chứng: Không hiển thị·đối tượng ma, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Đối tượng bị giữ lại do ước tính đồng hồ sai Clock estimate error holds or discards entities

Nếu giờ server mà client ước tính bị sai, client sẽ giữ lại thông tin đối tượng vừa tới vì cho là “vẫn còn ở tương lai”, hoặc bỏ đi vì cho là “quá cũ”.

Vì sao: Giờ server mà một client ước tính bị lệch nhiều (đo trong lúc loading, vừa thoát chế độ tiết kiệm điện) → Dẫn đến: Thời điểm mốc của nội suy và thời điểm trong thông tin đối tượng không khớp → Trên màn hình: Đối tượng xuất hiện muộn hoặc hiện ở trạng thái đứng yên

Triệu chứng: Không hiển thị·đối tượng ma, Giật khựng · Phụ trách chính Phát triển client (Đội phát triển game)

06Nguyên nhân thường gặp

Truyền lại TCP: nguyên nhân phát sinh và lý do độ trễ tăng lên

Khi chỉ số “truyền lại TCP (Retransmission)” trên server tăng, báo cáo lag thường cũng tăng theo. Truyền lại là tín hiệu cho biết “gói tin đã mất” hoặc “bên gửi xác định nhầm là đã mất”. Nguyên nhân có thể nằm ở bất cứ đâu trên đường đi, từ Wi-Fi đến card mạng server, và với kết nối gửi gói nhỏ thưa thớt như game, chỉ mất một gói cũng có thể lan thành đứng hình hàng trăm ms. Chương này tổng hợp nguyên nhân gốc của truyền lại, cách tìm nguyên nhân và hướng khắc phục.

Server gửiGame nhận123×Mất456124563Chờ gửi lại (tùy cách phục hồi)3Game không nhận được gì: đứng hình3·4·5·6 cùng lúc: tua nhanh
Đây là trường hợp một kết nối gửi 50 ms một lần và chỉ mất đúng gói số 3. TCP chỉ chuyển dữ liệu theo đúng thứ tự, nên dù gói 4, gói 5 và gói 6 đã đến, nó vẫn giữ lại, không chuyển cho game cho đến khi nhận lại được gói 3. Vì thế một lần mất gói biến thành đứng hình rồi tua nhanh ngay sau đó. Thời điểm gửi lại thay đổi theo cách phục hồi, từ khoảng một lượt khứ hồi đến “thời gian khứ hồi + tối thiểu 200 ms” khi phải chờ timer truyền lại (xem “Các loại truyền lại” bên dưới).

Bốn lý do truyền lại làm game chậm

  1. Chờ theo thứ tự (HOL blocking): TCP không chuyển các gói đến sau cho game cho đến khi nhận lại được gói bị mất. Mất một gói thì toàn bộ các gói phía sau cùng dừng lại rồi được giải phóng một lượt (đứng hình rồi tua nhanh).
  2. Thời gian chờ truyền lại: bên gửi chỉ gửi lại khi timer truyền lại (RTO) hết hạn. Trên Linux, thời gian này là “thời gian khứ hồi + tối thiểu 200 ms”. Nếu gói gửi lại cũng bị mất, thời gian chờ tăng gấp đôi sau mỗi lần (0,3 giây → 0,6 giây → 1,2 giây …).
  3. Thin stream (kết nối gửi gói nhỏ thưa thớt): truyền lại nhanh hoạt động dựa trên tín hiệu bên nhận báo “đã có 3 gói phía sau đến nơi” (3 ACK trùng lặp; ACK là xác nhận “đã nhận”). Gói tin của game cứ 50–200 ms mới có một gói, nên nhiều khi RTO hết hạn trước khi gom đủ tín hiệu. Đó là lý do tải file lớn vẫn chịu được mà riêng game lại đứng hình. RACK trên Linux đời mới chỉ cần một gói phía sau đến là đã xác định được, nhờ đó thu hẹp đáng kể khoảng cách này; nhưng nếu các gói cách nhau cỡ 200 ms thì RACK cũng không nhanh hơn RTO.
  4. Giảm lượng gửi: TCP coi mất gói là tín hiệu tắc nghẽn nên giảm lượng dữ liệu gửi mỗi lượt (cửa sổ tắc nghẽn). Nếu đã đến mức RTO, nó phải tăng dần lại từ trạng thái mỗi lượt chỉ gửi một gói. Trong lúc đó, các gói mới phát sinh dồn lại chờ trên server, và các gói cập nhật trạng thái lớn ở nơi đông người bị đẩy lùi nối đuôi nhau.

Các loại truyền lại

LoạiXảy ra khi nàoThời gian đến khi phục hồiBiểu hiện trong game
Truyền lại nhanh
Fast retransmit
Các gói phía sau đến trước, bên nhận báo “thiếu một gói ở giữa” (ACK trùng lặp, SACK)Thời gian khứ hồi + thời gian để 3 gói phía sau đến nơiKhựng ngắn. Gói càng dày thì càng nhanh
RACK, TLP
Xác định mất gói theo thời gian, gửi lại gói cuối
Khi gói gửi sau đã đến mà gói trước đó quá một khoảng thời gian vẫn chưa đến; hoặc khi một lúc lâu không có ACK thì gửi lại gói cuối thêm một lầnNgay sau khi có xác nhận của gói phía sau (RACK; vì có thể chỉ là đảo thứ tự nên chờ thêm khoảng 1/4 thời gian khứ hồi). Nếu không có gói phía sau thì khoảng 2 lần thời gian khứ hồi (TLP); nếu chỉ còn một gói chưa được xác nhận thì chờ thêm 200 ms để tính đến delayed ACKNgay cả với thin stream cũng chỉ khựng tương đối ngắn. Mặc định trên Linux đời mới
Truyền lại do RTO
Retransmission timeout
Khi hết thời gian chờ mà không có tín hiệu nàoThời gian khứ hồi + tối thiểu 200 ms, mỗi lần thất bại tăng gấp đôiĐứng hình hàng trăm ms đến vài giây rồi tua nhanh, kéo dài thì mất kết nối
Truyền lại SYNKhi chính yêu cầu kết nối bị mất (tràn backlog, tức hàng đợi kết nối; bị tường lửa chặn)1 giây, 2 giây, 4 giây, 8 giây … (Linux 6.5 trở lên gửi lại tối đa năm lần cách nhau 1 giây rồi mới tăng gấp đôi; Windows đời cũ bắt đầu từ 3 giây)Sau khi bấm kết nối, độ trễ rơi đúng vào số giây tròn như 1 giây, 3 giây; nếu thất bại liên tục thì không vào được·kẹt loading
Truyền lại không cần thiết
Spurious retransmission
Gói không mất nhưng đến muộn hoặc bị đảo thứ tự, bên gửi tưởng là mất nên gửi lạiKhông có gì cần phục hồi, chỉ có lượng gửi bị giảm (Linux có thể hoàn lại mức cũ nếu phát hiện được nhờ DSACK, tức thông báo “đã nhận rồi” của bên nhận, hoặc nhờ timestamp)Lãng phí đường truyền, tốc độ truyền dữ liệu lớn giảm. Trên chỉ số chỉ thấy tỷ lệ truyền lại cao
Zero window probe
Dễ nhầm với truyền lại
Gói bên gửi dùng để thăm dò khi bộ đệm bên nhận đã đầy và đang ở trạng thái “tạm thời đừng gửi”Cho đến khi bên nhận bắt đầu đọcĐứng hình. Đường truyền vẫn ổn, do chương trình bên nhận không đọc kịp

Cách tìm nơi làm mất gói

Tỷ lệ truyền lại là “tỷ lệ gói phải gửi lại trên tổng số gói đã gửi”. Giá trị cộng dồn từ lúc khởi động sẽ che mất biến động gần đây, nên hãy tính theo lượng tăng trong một khoảng cố định, chẳng hạn 1 phút. Không có ngưỡng chính thức, nhưng cảm giác đại khái với mức trung bình toàn server là: dưới 0,1% là khỏe, 0,1–1% là một số người chơi thỉnh thoảng bị khựng, trên 1% là nhiều người chơi cảm nhận được, trên 3% là nghiêm trọng. Game có nhiều người chơi dùng mobile hoặc ở nước ngoài sẽ có mức bình thường cao hơn. Vì vậy, thay vì kết luận từ một con số, hãy xem thêm nó tăng gấp mấy lần so với bình thường. Giá trị trung bình dễ bị vài đường truyền kém kéo lệch, nên chia nhỏ theo khu vực, nhà mạng, server, khung giờ là lối tắt để tìm ra nguyên nhân. Nếu ở giữa có thiết bị nhận kết nối rồi mở kết nối mới tới server (proxy, một số bộ cân bằng tải và gateway), chỉ số của server game chỉ ghi nhận chặng giữa thiết bị đó và server. Truyền lại phía người chơi phải xem trên thiết bị đó.

Xem ở đâuXem gìBiết được gì
Toàn server (Linux)Lượng tăng giữa hai lần chạy nstat cách nhau 1 phút: TcpRetransSegs ÷ TcpOutSegs, cùng các bộ đếm nhóm TcpExt là TCPTimeouts, TCPLossProbes và TCPLossProbeRecovery, TCPLostRetransmit, TCPSpuriousRTOs, TCPDSACKRecv, TCPSynRetransTỷ lệ truyền lại, số lần phải chờ đến RTO, số lần gửi TLP và trong đó bao nhiêu lần thực sự bù được gói mất, số lần ngay cả gói gửi lại cũng mất tiếp, số lần truyền lại yêu cầu kết nối. DSACK hoặc Spurious nhiều nghĩa là “không mất mà vẫn gửi lại”. OutSegs của Linux không tính phần truyền lại, nên tỷ lệ chính xác là RetransSegs ÷ (OutSegs + RetransSegs), nhưng ở mức quanh 1% thì chênh lệch nhỏ
Theo từng kết nối (Linux)retrans (đang phục hồi/cộng dồn), rto, backoff, rtt, cwnd, lost, reordering, bytes_retrans trong ss -tiCó phải chỉ một số người chơi hoặc khu vực truyền lại nhiều không, RTO đã tăng lên bao nhiêu (backoff là số lần RTO liên tiếp bị nhân đôi). bytes_retrans ÷ bytes_sent là tỷ lệ truyền lại của kết nối đó
Từng lần truyền lại (Linux)Công cụ eBPF tcpretrans (bcc). -c để thống kê theo kết nối, -l để tính cả TLPMỗi lần truyền lại in ra một dòng gồm IP, cổng của bên kia và trạng thái kết nối. Đây là cách nhẹ nhàng, không cần bắt gói, để xem truyền lại dồn vào dải địa chỉ người chơi nào hay server nào
Card mạng serverdropped, missed, crc trong ip -s -s link; rx_missed_errors, rx_no_buffer_count, rx_crc_errors, v.v. trong ethtool -S (tên khác nhau tùy driver, mlx5 là rx_out_of_buffer và rx_discards_phy); cột thứ 2 (dropped) và cột thứ 3 (time_squeeze) của /proc/net/softnet_statCard mạng server có bỏ gói ngay khi nhận không (ring buffer, CPU), hay dây mạng, module quang bị lỗi (CRC). softnet_stat mỗi CPU một dòng, ghi bằng số hệ 16 (hex). time_squeeze tăng liên tục nghĩa là core xử lý nhận không làm xong việc đúng hạn
Mạng cloudVới AWS ENA là bw_in_allowance_exceeded, bw_out_allowance_exceeded, pps_allowance_exceeded, conntrack_allowance_exceeded, linklocal_allowance_exceeded trong ethtool -S. Các chỉ số này không có trên màn hình CloudWatch mặc định, phải thu thập riêng bằng CloudWatch agentGói có bị bỏ âm thầm ở giới hạn của instance không. Giá trị đang tăng là đã vượt giới hạn. Các cloud khác cũng có giới hạn băng thông và số kết nối theo kích cỡ VM
Switch, router, tường lửaLỗi CRC và lỗi đầu vào của cổng, output drop, số lần vượt policer, mức dùng bảng phiên, log dropGói có bị bỏ ở chặng thiết bị trong trung tâm dữ liệu không. Mức sử dụng trung bình 5 phút thấp mà output drop tăng là microburst (lưu lượng dồn đến trong một khoảnh khắc rất ngắn)
Tuyến đườngMất gói kéo dài đến tận hop cuối trong mtr hoặc pathping. Phải gửi từ vài trăm lần trở lên mới thấy được mất gói cỡ 1%, và gửi tới cùng cổng TCP với game (mtr -T -P PORT) thì chính xác hơnMất gói bắt đầu từ hop thứ mấy. Nếu chỉ một hop ở giữa có vẻ mất gói mà các hop sau vẫn ổn, thì chỉ là thiết bị đó giới hạn tốc độ phản hồi cho gói đo (ICMP). Chiều đi và chiều về có thể khác tuyến, nên hãy đo cả từ phía server về phía người chơi
Bắt gói (cả hai đầu)Bộ lọc Wireshark tcp.analysis.retransmission, cùng fast_retransmission, spurious_retransmission, duplicate_ack, lost_segment, zero_window thuộc nhóm tcp.analysis.Gói gốc có trong bản bắt gói ở bên gửi mà không có ở bên nhận thì đã mất ở khoảng giữa. Nếu bên nhận cũng có thì đó là truyền lại không cần thiết, hoặc ACK trên đường về bị trễ hay bị mất. Gói bị bỏ ở ring buffer của server nhận cũng hiện ra trong bản bắt gói như “mất ở khoảng giữa”, nên hãy xem kèm bộ đếm của card mạng
Windows ServerTCPv4\Segments Retransmitted/sec ÷ Segments Sent/sec trong Performance Monitor, Network Interface\Packets Received Discarded, netsh int tcp show global, pktmon (có sẵn trong Windows 10 1809 và Windows Server 2019 trở lên)Xu hướng tỷ lệ truyền lại, card mạng có bỏ gói ngay khi nhận không, cấu hình TCP, gói bị bỏ ở đâu bên trong Windows

Thứ tự kiểm tra: khi xem cùng đội hạ tầng, đi theo thứ tự dưới đây là nhanh nhất.

  1. Khi nào, ai gặp: xem tỷ lệ truyền lại tăng từ lúc nào, có dồn vào một khu vực, nhà mạng, server hay khung giờ nào không.
  2. Có thật là mất gói không: nếu TCPSpuriousRTOs và DSACK cùng tăng, hãy nghi trước tiên là truyền lại không cần thiết, tức gói đến muộn bị tưởng là đã mất.
  3. Khâu nhận của server: nếu cùng thời điểm đó bộ đếm của card mạng, softnet hoặc giới hạn cloud tăng lên, thì gói đã bị bỏ ở phía server.
  4. Thiết bị trung tâm dữ liệu: xem bộ đếm drop và CRC cùng bảng phiên của switch và tường lửa.
  5. Tuyến đường bên ngoài: chạy mtr theo cả hai chiều, từ phía người chơi gặp sự cố và từ phía server, để tìm hop bắt đầu mất gói.
  6. Vẫn chưa rõ: bắt gói ở cả hai đầu vào cùng thời điểm rồi so sánh.

Nếu báo cáo có thời điểm (đến từng giây), nhà mạng và khu vực của người chơi, server đang vào và tên triệu chứng, đội hạ tầng có thể đi ngay theo thứ tự này.

Hướng khắc phục

1. Không để mất gói (khắc phục tận gốc)

  • Dùng dây mạng thay cho Wi-Fi, dùng băng tần 5 GHz hoặc 6 GHz, bật SQM và ECN trên router để giảm tràn hàng đợi
  • Không để server bắn toàn bộ dữ liệu cập nhật của một tick cùng lúc, hãy chia ra gửi rải trong tick. Việc một kết nối gửi dồn thì làm đều lại bằng pacing (fq, BBR, giới hạn tốc độ gửi)
  • Tăng ring buffer, phân tán ngắt ra nhiều core, kiểm tra giới hạn của cloud
  • Thay dây mạng hoặc module quang có lỗi CRC, chỉnh cấu hình duplex cho khớp
  • Dùng shaper (đưa phần vượt vào hàng đợi rồi đẩy ra từ từ) thay cho policer (bỏ ngay phần vượt), tăng mức burst cho phép
  • Để dư dung lượng cho bảng của tường lửa và bảng theo dõi kết nối (conntrack) cũng như số gói mỗi giây của các thiết bị trung gian; bảo đảm chiều đi và chiều về đi qua cùng một tường lửa
  • Ngăn MTU black hole bằng cách chỉnh MSS (kích thước dữ liệu tối đa trong một gói) và cho phép thông báo ICMP báo gói vượt kích thước; dò MTU chỉ là lưới an toàn cuối cùng. Duy trì ánh xạ NAT và LB bằng heartbeat do client gửi

2. Phục hồi nhanh hơn

  • Kiểm tra để SACK và timestamp không bị tắt trong cấu hình server hay bị thiết bị trung gian xóa mất (không có SACK thì RACK-TLP cũng không hoạt động)
  • Dùng RACK-TLP (mặc định trên Linux và Android đời mới). Chiều client gửi, như input của bạn, do OS phía client phục hồi nên cấu hình server không thay đổi được (Windows bật sẵn TLP và RACK từ Windows 10 (1607) và Windows Server 2016; RACK mới, phục hồi được cả gói truyền lại bị mất, có từ Windows Server 2022)
  • Với thin stream, dùng tcp_thin_linear_timeouts; từ Linux 6.15 trở lên có thể hạ giới hạn trên của RTO bằng TCP_RTO_MAX_MS
  • Bật TCP_NODELAY cho kết nối game (nếu Nagle giữ gói mới lại, không gửi đi, RACK sẽ mất các gói phía sau mà nó cần dùng)
  • Với kết nối giữa các server trong mạng nội bộ, hạ giá trị RTO tối thiểu theo từng tuyến (ip route … rto_min)
  • Dùng TCP_USER_TIMEOUT và heartbeat của game để sớm cắt kết nối đã chết rồi kết nối lại

3. Giảm độ nhạy với truyền lại (kiến trúc)

  • Vị trí và chiến đấu thời gian thực thì chạy trên UDP, chỉ gửi lại những gì cần thiết (vị trí cũ không đáng gửi lại). Với input, nếu mỗi gói gửi kèm vài input gần nhất thì khi mất một gói, gói kế tiếp vẫn bù được
  • Tách những thứ cần đúng thứ tự như chat, giao dịch khỏi các gói thời gian thực, cho chạy trên các luồng khác nhau (stream của QUIC, chia thành nhiều kết nối TCP, v.v.). Mất gói ở bên này không chặn bên kia
  • Nếu vẫn dùng TCP, hãy ghi đè bằng trạng thái mới nhất thay vì để vị trí cũ tích lại trong bộ đệm gửi (TCP_NOTSENT_LOWAT, v.v.). Đoạn tua nhanh sau một lần đứng hình dài sẽ ngắn lại
  • Dùng bộ đệm nội suy và dự đoán để che những lần khựng ngắn trên màn hình. Khó mà che được lần đứng hình do RTO kéo dài hàng trăm ms

Tổng hợp tên cấu hình: cấu hình cần bật và cấu hình dễ nhầm lẫn

Phần lớn cấu hình liên quan đến phục hồi truyền lại là cấu hình của hệ điều hành (kernel), chỉ có vài tùy chọn socket bật riêng được cho kết nối game. TCP_NODELAY hay bị nhầm vì cái tên, nhưng nó không làm phục hồi nhanh hơn. Tuy vậy, nếu không bật (tức vẫn dùng Nagle), gói mới sẽ còn trễ hơn trong lúc phục hồi. Bảng dưới đây tính theo Linux; Windows có tên gọi và phạm vi hỗ trợ khác.

Cấu hìnhỞ đâuThay đổi gìCần chú ý
TCP_NODELAYTùy chọn socketTắt Nagle. Gửi message nhỏ ngay, không gom lạiLoại bỏ khoảng chờ 40–200 ms vốn xảy ra cả khi không mất gói. Bản thân timer truyền lại (RTO) không đổi. Tuy vậy, nếu Nagle đang bật, trong lúc chờ phục hồi các gói mới cũng bị giữ lại nên sau khi phục hồi phải chờ thêm một lượt khứ hồi nữa; các gói phía sau mà truyền lại nhanh và RACK dựa vào cũng không có, nên dễ đi đến RTO. Game thường bật tùy chọn này
net.ipv4.tcp_recovery (RACK)Cấu hình kernelXác định mất gói theo thời gian. Chịu được đảo thứ tự tốt và phục hồi nhanh cả với thin streamGiá trị mặc định 1 (bật). Được đưa vào Linux 4.4 và có dạng như hiện nay vào khoảng 4.18. Từ 6.17, RACK là cách xác định mất gói duy nhất nên đổi sang 0 cũng không có tác dụng. Không hoạt động trên kết nối không có SACK
net.ipv4.tcp_early_retrans (TLP)Cấu hình kernelNếu một lúc (khoảng 2 lần thời gian khứ hồi) không có ACK thì gửi lại gói cuối thêm một lần để sớm phát hiện mất các gói cuối (tail loss)Giá trị mặc định 3 (bật), 0 là tắt. Cần có SACK mới hoạt động. Nếu chỉ còn một gói chưa nhận được ACK (in-flight), nó chờ thêm 200 ms nên chậm gần bằng RTO
net.ipv4.tcp_sack, tcp_dsack, tcp_timestampsCấu hình kernelACK chọn lọc (SACK, báo phần bị thiếu ở giữa), thông báo nhận trùng (DSACK), đo thời gian khứ hồi (timestamp)Mặc định bật tất cả. Có những server đã tắt đi khi xảy ra lỗ hổng bảo mật SACK năm 2019 và vẫn để nguyên như vậy. Tắt SACK thì RACK và TLP cũng ngừng hoạt động theo
net.ipv4.tcp_thin_linear_timeouts / TCP_THIN_LINEAR_TIMEOUTSCấu hình kernel / tùy chọn socketVới kết nối có dưới 4 gói chưa nhận được ACK (in-flight), RTO không bị nhân đôi trong 6 lần đầuMặc định tắt. Có thể bật riêng cho kết nối game bằng tùy chọn socket. Không rút ngắn lần RTO đầu tiên
TCP_RTO_MAX_MS / net.ipv4.tcp_rto_max_msTùy chọn socket / cấu hình kernel (Linux 6.15 trở lên)Hạ giới hạn trên (mặc định 120 giây) của RTO vốn tăng gấp đôi mỗi lần. Tối thiểu 1 giâyKhông để RTO tăng lên vài chục giây sau nhiều lần mất gói liên tiếp. Việc phát hiện kết nối đã chết cũng nhanh hơn
net.ipv4.tcp_mtu_probingCấu hình kernelNếu gói lớn liên tục biến mất thì giảm kích thước để đi qua MTU black holeMặc định 0 (tắt). 1 = chỉ giảm khi truyền lại kéo dài khoảng 3 giây và nghi có black hole (trong thời gian đó bị đứng hình). 2 = ngay từ đầu bắt đầu ở 1.024 byte rồi tăng dần để thử
ip route … rto_minCấu hình tuyến (route)Hạ giá trị RTO tối thiểu (mặc định 200 ms) của tuyến đóChỉ dùng cho mạng nội bộ giữa các server. Hạ trên chặng Internet sẽ làm tăng truyền lại không cần thiết. net.ipv4.tcp_rto_min_us của Linux 6.11 trở lên là giá trị cho toàn server, nên kết nối Internet cũng bị đổi theo. Từ 6.15 có thể dùng tùy chọn socket TCP_RTO_MIN_US để chỉ hạ cho kết nối nội bộ
TCP_USER_TIMEOUTTùy chọn socketThời gian chờ trước khi bỏ kết nối khi truyền lại cứ tiếp diễnKhông làm phục hồi nhanh hơn. Giúp sớm cắt kết nối đã chết để kết nối lại. Nếu không đặt, Linux sẽ truyền lại khoảng 15 lần, kéo dài chừng 15 phút mới cắt (tcp_retries2)
SO_KEEPALIVE + TCP_KEEPIDLE, v.v.Tùy chọn socketKiểm tra kết nối nhàn rỗi còn sống khôngKhông liên quan đến truyền lại. Dùng để duy trì ánh xạ NAT, LB và phát hiện kết nối đã chết
Qdisc fq + SO_MAX_PACING_RATE, BBRCấu hình qdisc / tùy chọn socket / cấu hình kernelRải đều các gói khi gửi để giảm mất gói do burst (gửi dồn một lượt)Thuộc nhóm “phòng ngừa” mất gói. Không liên quan đến tốc độ phục hồi

Nguyên nhân gốc của truyền lại TCP

Mất gói ở chặng không dây Wi-Fi / cellular link loss

Wi-Fi và mạng di động tự truyền lại vài lần trên chặng không dây, nếu vẫn không được thì bỏ gói tin. Gói đã bị bỏ phải đợi khá lâu sau đó TCP mới gửi lại.

Vì sao: Sóng yếu hoặc nhiễu mạnh khiến việc truyền trên chặng không dây thất bại liên tiếp → Dẫn đến: Vượt giới hạn số lần thử lại của thiết bị không dây (thường từ vài lần đến hơn chục lần) thì gói tin bị bỏ → Trên màn hình: Đứng hình trong lúc chờ TCP truyền lại, các gói phía sau nằm chờ trong bộ đệm nhận rồi tua nhanh

Triệu chứng: Đứng hình, Tua nhanh, Dịch chuyển tức thời · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Hạ tầng server (Đội hạ tầng), Phát triển server (Đội phát triển game), Phát triển client (Đội phát triển game)

Tràn hàng đợi ở điểm nghẽn (mất gói do tắc nghẽn) Tail drop at a congested bottleneck

Khi hàng đợi ở chỗ hẹp nhất trên đường đi (router, chặng kết nối giữa các nhà mạng, đường truyền của trung tâm dữ liệu) đầy, gói tin mới đến sẽ bị bỏ.

Vì sao: Video, tải file hoặc lưu lượng của người dùng khác làm điểm nghẽn đầy → Dẫn đến: Trong lúc hàng đợi đầy, các gói mới đến liên tiếp bị bỏ (tail drop). Gói không bị bỏ cũng phải chờ ở cuối hàng đợi đang đầy → Trên màn hình: Nhiều gói biến mất cùng lúc nên đứng hình lâu rồi tua nhanh, hay gặp vào buổi tối

Triệu chứng: Đứng hình, Tua nhanh, Kéo ngược · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Bên ngoài (Bên ngoài), Phát triển client (Đội phát triển game)

Burst gửi làm tràn bộ đệm nhỏ Sender bursts overflow shallow buffers

Mỗi tick, nếu server dồn bản cập nhật cho hàng nghìn người rồi gửi đi trong một khoảnh khắc, bộ đệm nhỏ của switch hoặc giới hạn tức thời của cloud sẽ tràn trong chưa đầy 1 ms và một phần gói tin bị bỏ.

Vì sao: Ngay đầu tick, server gửi dồn một lượt toàn bộ gói tin cho mọi người → Dẫn đến: Bộ đệm của cổng switch nơi lưu lượng từ nhiều server dồn về (vài trăm KB đến vài MB mỗi cổng) hoặc giới hạn của instance cloud bị tràn trong khoảnh khắc (mức sử dụng trung bình vẫn thấp) → Trên màn hình: Nhiều người cùng lúc bị dịch chuyển tức thời hoặc khựng, nhìn chỉ số trung bình thì không thấy nguyên nhân

Triệu chứng: Dịch chuyển tức thời, Đứng hình, Tua nhanh · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng), Hạ tầng mạng (Đội hạ tầng)

Policer bỏ phần vượt mức Traffic policing

Gói cước của nhà mạng, giới hạn của instance cloud và thiết bị chống DDoS đôi khi bỏ ngay các gói vượt tốc độ quy định mà không đưa vào hàng đợi.

Vì sao: Lượng dữ liệu gửi tức thời vượt tốc độ cho phép hoặc burst cho phép → Dẫn đến: Gói vượt mức bị bỏ ngay, không qua hàng đợi (policing) → Trên màn hình: Mỗi lúc burst lớn lại mất nhiều gói nên đứng hình rồi tua nhanh, trong khi tốc độ trung bình trông vẫn dưới giới hạn

Triệu chứng: Đứng hình, Tua nhanh, Dịch chuyển tức thời · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Hạ tầng server (Đội hạ tầng), Phát triển server (Đội phát triển game)

Lỗi vật lý (cáp, module quang, đầu nối hỏng) Bit errors: bad cable, optics, dirty fiber

Cáp bị hỏng, đầu nối quang bám bụi, module quang hết tuổi thọ sẽ gây lỗi bit, và thiết bị âm thầm bỏ các gói bị hỏng.

Vì sao: Cáp, module quang hoặc đầu nối hỏng làm bit bị đảo → Dẫn đến: Thiết bị bỏ gói có checksum (CRC) không khớp → Trên màn hình: Chỉ những người đi qua tuyến đó bị khựng ngắn rồi tua nhanh một cách đều đặn, không liên quan khung giờ

Triệu chứng: Đứng hình, Tua nhanh, Dịch chuyển tức thời · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Hạ tầng server (Đội hạ tầng), Bên ngoài (Bên ngoài)

Không khớp chế độ duplex Duplex mismatch

Nếu một đầu để tự động đàm phán (auto-negotiation) còn đầu kia cố định tốc độ và duplex, một bên sẽ chạy half-duplex và mỗi lần có tải lại mất gói do va chạm (collision).

Vì sao: Chỉ một đầu thiết bị cố định cấu hình tốc độ và duplex → Dẫn đến: Một bên chạy full-duplex, bên kia chạy half-duplex nên xảy ra va chạm và va chạm muộn (late collision) → Trên màn hình: Bình thường không sao, nhưng khi lưu lượng tăng thì mọi người đi qua thiết bị đó đều đứng hình rồi tua nhanh

Triệu chứng: Đứng hình, Tua nhanh · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Hạ tầng server (Đội hạ tầng)

Host server nhận bỏ gói tin Receiver host drops (ring, softirq, CPU)

Gói tin đã đến được server nhưng bị bỏ vì ring buffer của NIC (bộ đệm tạm giữ gói tin vừa đến) bị tràn, hoặc core xử lý nhận gói của kernel bị bão hòa.

Vì sao: Số người vào tăng vọt, ngắt dồn vào một core, CPU steal trên máy ảo, switch ảo quá tải → Dẫn đến: Bị bỏ ở ring buffer (rx_missed_errors và các counter tương tự, tên khác nhau tùy driver) hoặc ở hàng đợi nhận của kernel (softnet dropped) → Trên màn hình: Khi đông người, cả server cùng lúc bị trễ thao tác và khựng

Triệu chứng: Trễ thao tác, Đứng hình, Tua nhanh, Dịch chuyển tức thời · Phụ trách chính Hạ tầng server (Đội hạ tầng)

Tường lửa và theo dõi kết nối bỏ gói Stateful firewall / conntrack drops

Tường lửa hoặc tính năng theo dõi kết nối của Linux (conntrack, ghi các kết nối đi qua vào một bảng) sẽ bỏ gói tin khi bảng đầy hoặc khi xác định trạng thái kết nối không khớp.

Vì sao: Bảng theo dõi kết nối đầy (table full), hoặc chiều đi và chiều về khác đường nên chỉ một chiều đi qua tường lửa (tuyến đường bất đối xứng) → Dẫn đến: Tường lửa coi đó là gói của “kết nối lạ” hoặc có “số thứ tự nằm ngoài phạm vi cửa sổ” rồi bỏ đi → Trên màn hình: Bảng đầy thì kết nối mới bị chặn; tuyến đường lệch thì chỉ người đi tuyến đó bị truyền lại liên tục rồi mất kết nối

Triệu chứng: Đứng hình, Mất kết nối, Không vào được·kẹt loading · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Hạ tầng server (Đội hạ tầng), Phát triển server (Đội phát triển game), Phát triển client (Đội phát triển game)

Thiết bị trung gian vượt giới hạn xử lý (tường lửa, IPS, chống DDoS) Inline appliance PPS / CPU overload

Tường lửa, thiết bị chống xâm nhập (IPS) và thiết bị chống DDoS kiểm tra từng gói tin đi qua. Từ lúc vượt năng lực kiểm tra, thiết bị bỏ những gói không xử lý kịp.

Vì sao: Giờ cao điểm hoặc sự kiện làm hơn vài trăm nghìn gói game nhỏ dồn tới mỗi giây, hoặc bộ luật kiểm tra quá nặng → Dẫn đến: CPU hoặc giới hạn số gói mỗi giây của thiết bị đã đầy nên thiết bị bỏ gói. Nếu phát hiện nhầm (false positive) thì cả gói bình thường cũng bị chặn → Trên màn hình: Toàn bộ server phía sau thiết bị đó cùng lúc bị đứng hình hoặc dịch chuyển tức thời, chỉ nặng lên khi đông người

Triệu chứng: Đứng hình, Tua nhanh, Dịch chuyển tức thời, Mất kết nối · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

MTU black hole (chỉ gói lớn liên tục bị mất) PMTU black hole

Khi kích thước tối đa mà một chặng giữa đường nhận được bị giảm đi nhưng thông báo “quá lớn” (ICMP) lại bị chặn, gói lớn gửi lại bao nhiêu lần cũng tiếp tục biến mất.

Vì sao: Kích thước tối đa giảm ở chặng VPN hoặc tunnel, còn thông báo vượt kích thước bị tường lửa chặn → Dẫn đến: Bên gửi không biết lý do nên cứ truyền lại cùng một gói lớn, RTO tăng gấp đôi sau mỗi lần → Trên màn hình: Bình thường không sao, nhưng vào lúc có dữ liệu lớn đi qua (mở túi đồ, đến chỗ đông người, loading khi vào khu vực mới) thì cả các gói nhỏ phía sau cũng bị kẹt theo và game đứng hình, cuối cùng mất kết nối hoặc kẹt loading

Triệu chứng: Đứng hình, Mất kết nối, Không vào được·kẹt loading · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Hạ tầng server (Đội hạ tầng), Phát triển server (Đội phát triển game)

Ánh xạ NAT hoặc bộ cân bằng tải hết hạn giữa chừng kết nối NAT / load balancer mapping expired mid-connection

Nếu thiết bị trung gian xóa ánh xạ (mapping: mục ghi lại kết nối này cần được chuyển tới đâu) của một kết nối nhàn rỗi, gói gửi tiếp theo sẽ không được chuyển đi. Bên gửi chỉ truyền lại liên tục rồi mất kết nối, hoặc thiết bị gửi trả gói từ chối kết nối (RST) khiến kết nối đứt ngay.

Vì sao: Kết nối không có gói nào đi lại trong một thời gian (người chơi rời máy, đứng ở sảnh chờ) → Dẫn đến: NAT của router, CGNAT của nhà mạng, tường lửa, bộ cân bằng tải hoặc security group của cloud xóa ánh xạ nhàn rỗi → Trên màn hình: Lúc hoạt động trở lại thì truyền lại liên tiếp rồi mất kết nối, hoặc mất kết nối ngay

Triệu chứng: Mất kết nối, Đứng hình · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game), Hạ tầng mạng (Đội hạ tầng), Hạ tầng server (Đội hạ tầng)

Đổi tuyến đường hoặc tuyến ECMP lỗi Route change / bad ECMP member

Gói tin biến mất trong vài giây lúc tuyến đường Internet thay đổi, hoặc trên kết nối được gán vào tuyến lỗi trong số nhiều tuyến ECMP.

Vì sao: BGP tính lại tuyến đường, hoặc thiết bị hay đường truyền của một tuyến trong số nhiều tuyến (ECMP, LAG) bị lỗi → Dẫn đến: Mất gói tạm thời trong lúc chuyển tuyến, hoặc chỉ kết nối đi tuyến đó bị mất gói đều đặn → Trên màn hình: Đột nhiên đứng hình vài giây rồi tua nhanh, hoặc “kết nối lại thì đỡ” (được gán sang tuyến khác)

Triệu chứng: Đứng hình, Tua nhanh, Dịch chuyển tức thời · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game), Bên ngoài (Bên ngoài)

Truyền lại không cần thiết do độ trễ tăng vọt Spurious RTO from delay spikes

Gói tin vẫn đến nơi, chỉ là đến rất muộn trong chốc lát; nếu độ trễ đó dài hơn RTO thì bên gửi xác định là mất rồi truyền lại.

Vì sao: Bufferbloat, chế độ tiết kiệm điện của Wi-Fi, mạng di động chuyển trạng thái vô tuyến, máy ảo bị tạm dừng làm độ trễ tức thời lên vài trăm ms → Dẫn đến: RTO hết hạn trước nên truyền lại, gói gốc cũng đến ngay sau đó (bên nhận nhận trùng) → Trên màn hình: Đứng hình và tua nhanh là do chính độ trễ tăng vọt. Truyền lại không cần thiết hầu như không làm đứng hình lâu hơn, chỉ đẩy chỉ số truyền lại lên nên bị hiểu nhầm là mất gói

Triệu chứng: Đứng hình, Tua nhanh, Trễ thao tác · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Hạ tầng server (Đội hạ tầng), Phát triển client (Đội phát triển game)

Truyền lại nhanh không cần thiết do gói đến sai thứ tự Reordering triggers spurious fast retransmit

Khi đi qua nhiều tuyến hoặc các link được gộp, thứ tự gói tin có thể bị đảo; bên nhận dùng ACK trùng (duplicate ACK) để báo “có gói bị thiếu”, và bên gửi gửi lại cả gói vẫn còn nguyên vẹn.

Vì sao: Thiết bị chia tuyến theo từng gói, LAG (gộp link) chia tải theo từng gói, hoặc khoảnh khắc đổi tuyến làm xáo trộn thứ tự → Dẫn đến: Gói phía sau đến trước nên dồn đủ 3 ACK trùng → truyền lại nhanh → Trên màn hình: Gói game đi lại thưa thớt nên gần như không bị ảnh hưởng. Bản cập nhật trạng thái lớn ở chỗ đông người và việc tải bản cập nhật (patch) bị chậm lại, thỉnh thoảng giật khựng

Triệu chứng: Giật khựng, Trễ thao tác · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Hạ tầng server (Đội hạ tầng)

ACK đến muộn hoặc bị mất (chiều tải lên bị bão hòa) ACK path congestion on asymmetric links

Dữ liệu đã đến nơi, nhưng nếu ACK báo “đã nhận” bị trễ hoặc bị mất trong hàng đợi upload đang đầy, bên gửi sẽ xác định là mất gói rồi truyền lại.

Vì sao: Ở nhà có người upload video hoặc sao lưu lên cloud làm chiều tải lên bị đầy → Dẫn đến: ACK bị trễ vài trăm ms trong hàng đợi của router, hoặc bị bỏ vì hàng đợi tràn → Trên màn hình: Gói server game gửi xuống nhìn chung vẫn đến đúng lúc. Input của bạn nằm chung hàng đợi upload nên bị chậm, gây trễ thao tác và kéo ngược, thỉnh thoảng có truyền lại không cần thiết

Triệu chứng: Trễ thao tác, Kéo ngược · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Cấu hình RTO không hợp với môi trường RTO min too low or too high

Hạ RTO tối thiểu quá thấp thì chỉ trễ một chút cũng sinh ra truyền lại không cần thiết, còn giá trị mặc định (200 ms) lại quá dài với game nên mỗi lần mất gói là đứng lâu.

Vì sao: Hạ mạnh RTO tối thiểu theo kiểu dành cho trung tâm dữ liệu, hoặc để nguyên giá trị mặc định cho chặng Internet → Dẫn đến: Thấp thì chỉ một thoáng trễ cũng làm truyền lại ồ ạt, cao thì mỗi lần mất gói phải chờ lâu → Trên màn hình: Với giá trị mặc định, mỗi lần mất gói là đứng hình vài trăm ms rồi tua nhanh; hạ quá thấp thì đứng hình ít đi nhưng truyền lại không cần thiết tăng vọt, lãng phí đường truyền

Triệu chứng: Đứng hình, Tua nhanh, Trễ thao tác · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Thin stream phục hồi chậm Thin streams fall back to RTO

Khi gửi gói nhỏ thưa thớt như game, RTO đến trước khi gom đủ “3 gói theo sau”. Với cùng mức mất gói, game đứng lâu hơn nhiều so với khi truyền dữ liệu dung lượng lớn.

Vì sao: Khoảng cách giữa các gói khoảng 100 ms nên chỉ có vài gói chưa nhận được ACK (in-flight) → Dẫn đến: Để gom đủ 3 ACK trùng phải mất hơn 300 ms nên RTO (ping + 200 ms) kích hoạt trước; mất liên tiếp thì mỗi lần tăng gấp đôi → Trên màn hình: Mỗi lần mất gói đứng hình khoảng 0,3 giây; nếu mất cả gói đã gửi lại thì đứng gần 1 giây rồi tua nhanh

Triệu chứng: Đứng hình, Tua nhanh · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng), Phát triển client (Đội phát triển game)

Thiết bị trung gian xóa tùy chọn TCP Middlebox strips TCP options

Nếu một số tường lửa hoặc thiết bị tăng tốc xóa hay sửa tùy chọn TCP, khi mất nhiều gói thì mỗi vòng khứ hồi chỉ phục hồi được một gói, hoặc cửa sổ (lượng dữ liệu gửi được trong một lần) bị thu nhỏ, khiến kết nối chậm đi.

Vì sao: “Chuẩn hóa TCP” (TCP normalization) của tường lửa hoặc thiết bị tăng tốc đời cũ xóa các tùy chọn SACK, timestamp, window scale → Dẫn đến: Mất nhiều gói thì mỗi vòng khứ hồi chỉ phục hồi một gói, cửa sổ bị giới hạn ở 64 KB → Trên màn hình: Mỗi lần mất gói, thời gian đứng hình dài hơn nhiều (không có SACK thì cũng không dùng được RACK-TLP), thông rồi thì tua nhanh. Truyền dữ liệu dung lượng lớn như tải bản cập nhật cũng chậm

Triệu chứng: Đứng hình, Tua nhanh · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Hạ tầng server (Đội hạ tầng)

Zero window (khoảng dừng dễ nhầm là truyền lại) Zero window, often mistaken for retransmission

Nếu chương trình bên nhận không đọc socket kịp khiến bộ đệm đầy, bên gửi sẽ ngừng gửi và chỉ gửi zero window probe. Đường truyền không có vấn đề gì.

Vì sao: Client bị đứng khung hình, thread server bị chặn nên không đọc được socket → Dẫn đến: Cửa sổ nhận về 0 nên bên gửi ngừng gửi và chỉ gửi probe (khoảng cách thưa dần) → Trên màn hình: Đứng hình rồi tua nhanh. Bản bắt gói có “ZeroWindow” và không có mất gói

Triệu chứng: Đứng hình, Tua nhanh · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game), Hạ tầng server (Đội hạ tầng)

Truyền lại yêu cầu kết nối (SYN) SYN retransmission on connect

Khi yêu cầu kết nối biến mất do hàng đợi kết nối (backlog) bị tràn hoặc bị tường lửa chặn, OS phía client sẽ gửi lại, bắt đầu sau 1 giây và giãn dần khoảng cách.

Vì sao: Ngay sau bảo trì, lượng kết nối dồn vào làm tràn hàng đợi kết nối của server, hoặc tường lửa hay hệ thống chống DDoS bỏ SYN → Dẫn đến: OS phía client truyền lại SYN theo khoảng cách định sẵn, bắt đầu sau 1 giây (Linux đời cũ là 1 giây → 2 giây → 4 giây) → Trên màn hình: Sau khi bấm nút kết nối, thời gian trễ tròn đúng từng giây như 1 giây, 3 giây; thất bại liên tục thì không vào được game hoặc kẹt loading

Triệu chứng: Không vào được·kẹt loading · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng), Hạ tầng mạng (Đội hạ tầng), Phát triển client (Đội phát triển game)

07Phân công phụ trách

Phạm vi phụ trách của đội phát triển game và đội hạ tầng

Cùng là lag nhưng nơi sửa có thể khác nhau. Code client, server và thiết kế đồng bộ do đội phát triển game phụ trách; đường truyền, thiết bị mạng, thiết bị server và thiết bị DB do đội hạ tầng phụ trách. Với vấn đề ở PC và mạng gia đình của người chơi, chặng của nhà mạng hay phía nhà cung cấp cloud, cả hai đội đều không tự sửa được nên xử lý bằng cách hướng dẫn, gửi yêu cầu hoặc đi đường vòng. Mỗi thẻ nguyên nhân đều ghi phụ trách chính và bên phối hợp; mở phần “Con số tham khảo·Cách xác nhận·Việc của từng đội” trên thẻ sẽ thấy việc cần làm được chia theo từng đội.

  1. Báo cáo, cảnh báoTriệu chứng, thời điểm đến từng giây, server và kênh
  2. Ai gặp phảiMột người, một nhà / một nhà mạng hoặc khu vực / một server hoặc kênh / tất cả
  3. Gọi ai trướcBên phụ trách chính của các thẻ nguyên nhân ứng viên. Mục “Kiểm tra trước” trong công cụ chẩn đoán
  4. Thông tin cần chuyểnIP và nhà mạng, lý do mất kết nối, đồ thị liên quan, thay đổi ngay trước đó
  5. Việc làm chungChia việc theo mục việc của từng đội trên thẻ
Đây là quy trình từ lúc nhận ticket đến lúc chia thành việc của từng đội. “Ai gặp phải” là yếu tố phân định bên phụ trách rõ nhất; tiêu chí chi tiết có trong bảng dưới đây và chương Chẩn đoán từ dữ liệu quan sát.
Phụ tráchPhạm vi phụ tráchCách khắc phục thường dùng
Đội phát triển gameClientCode client game: khung hình, GC, loading; nội suy, ngoại suy, dự đoán; xử lý mạng phía client (gồm gửi heartbeat và tự động kết nối lại)Sửa code, điều chỉnh bộ đệm nội suy và dự đoán, thay đổi cách loading, khoảng cách heartbeat và quy trình kết nối lại, bản cập nhật client
Đội phát triển gameServerCode server game: tick, thread, lock; thiết kế đồng bộ; xử lý kết nối (vòng lặp accept, tham số listen); phản hồi heartbeat và dọn các kết nối đã đứt; tùy chọn socket; thiết kế query và transactionTối ưu logic, gọi bất đồng bộ, phân tán tải theo tick và khu vực, hàng chờ đăng nhập, nối lại phiên bằng session token, tùy chọn socket (TCP_NODELAY, v.v.), thiết kế query và index, bản cập nhật server
Đội hạ tầngMạngĐường truyền và thiết bị mạng trong IDC (switch, router, tường lửa, bộ cân bằng tải, chống DDoS); network ACL, định tuyến VPC và bộ cân bằng tải trên cloud; nhà mạng và peeringCấu hình và thay thiết bị, nâng cấp đường truyền và peering, đổi tuyến đường, escalate lên nhà mạng, điều chỉnh idle timeout và giới hạn phiên của bộ cân bằng tải và tường lửa
Đội hạ tầngThiết bị server·OSPhần cứng server và instance cloud (gồm security group và theo dõi kết nối), cấu hình OS và kernel, NIC, môi trường triển khai và giám sátNâng cấp, đổi loại instance, cấu hình kernel (sysctl: somaxconn, conntrack, v.v.), thiết lập security group và thời gian theo dõi kết nối, ring buffer của NIC và phân tán ngắt, điều chỉnh giờ chạy cron và sao lưu
Đội hạ tầngThiết bị DBServer DB và storage; cấu hình, replication và sao lưu DB; server cacheNâng cấp DB, bảo đảm IOPS cho storage, tham số DB và cấu hình replication, điều chỉnh sao lưu và checkpoint
Bên ngoàiNgười chơi·nhà mạng·cloudPC và mạng gia đình của người chơi, chặng của nhà mạng (ngoài phạm vi hợp đồng của chúng ta), nhà cung cấp cloudHướng dẫn người chơi (dùng dây mạng, v.v.), gửi yêu cầu tới nhà mạng và nhà cung cấp cloud, workaround và giảm nhẹ phía game

Tổng quan phụ trách theo tầng và chủ đề

Số in đậm là số nguyên nhân mà bên đó phụ trách chính, số có dấu + là số nguyên nhân bên đó phối hợp xử lý. Bấm vào một ô để xem các nguyên nhân đó và việc cần làm của đội ở bên dưới.

Khi ranh giới không rõ: đội có nguyên nhân là phụ trách chính, đội khác giảm nhẹ và kiểm tra

Phụ trách chính là nơi có nguyên nhân gốc, hoặc nơi có thể loại bỏ nó. Dù nguyên nhân là đường truyền hay thiết bị, trong thời gian chờ khắc phục đội phát triển game vẫn cầm cự bằng các thiết kế giảm ảnh hưởng (bộ đệm nội suy, gửi lặp input, kết nối lại); còn nếu nguyên nhân là code server thì đội hạ tầng có thêm thiết bị cũng chỉ trì hoãn được một thời gian. Các ranh giới hay bị nhầm được quy định như sau.

  • Để yên một lúc thì mất kết nối: chúng ta không thay đổi được idle timeout của router nhà người chơi và thiết bị nhà mạng, và ánh xạ đó chỉ được duy trì chắc chắn bằng gói tin đi từ bên trong ra. Vì vậy client gửi heartbeat và tự động kết nối lại khi bị ngắt; server phản hồi heartbeat, nếu không nhận được thì chủ động dọn kết nối trước, rồi nối lại phiên bằng session token. Đội hạ tầng cung cấp giá trị timeout của thiết bị phía mình và tăng lên khi cần.
  • Tràn hàng đợi kết nối (backlog): giới hạn thực nằm ở tham số listen và vòng lặp accept trong code server, nên nhóm phát triển server phụ trách chính, còn nhóm thiết bị server·OS lo giới hạn trên của kernel (somaxconn) và SYN cookie.
  • Cloud: security group và theo dõi kết nối của instance do nhóm thiết bị server·OS phụ trách; network ACL, định tuyến VPC và bộ cân bằng tải của cloud do nhóm mạng phụ trách.

Nhãn “Trước tiên” trong bảng chỉ nơi cần gọi đầu tiên, được xác định bằng cách đếm bên phụ trách chính của các thẻ nguyên nhân ứng với hiện tượng đó. Nếu có hai nơi, nơi đứng trước là nơi làm phụ trách chính ở nhiều thẻ nhất, nơi đứng sau là nơi nên gọi cùng ngay từ đầu.

Hiện tượngViệc của đội phát triển gameViệc của đội hạ tầngChỉ số cần xem trước
Mất gói và jitter lớn ở một nhà mạng hoặc khu vực
Trước tiênĐội hạ tầngMạng
Bộ đệm nội suy thích ứng, gửi lặp input, truyền UDP chịu được mất gói, trích IP, cổng và thời điểm của người gặp sự cố từ thống kê mất gói và truyền lại theo từng kết nối, nới tiêu chí kiểm tra di chuyển tương ứng với tình trạng đường truyềnĐo tuyến đường hai chiều bằng cùng giao thức và cổng với game (mtr), bỏ tuyến kém, escalate lên nhà mạng, thêm peering và đường truyềnPhân bố tỷ lệ mất gói và jitter theo nhà mạng, tỷ lệ truyền lại
Truyền lại TCP tăng
Trước tiênĐội hạ tầngMạngĐội phát triển gameServer
TCP_NODELAY, chia phần gửi của một tick rải ra trong tick, đọc socket kịp thời (tránh zero window), duy trì ánh xạ bằng heartbeat, chuyển gói thời gian thực sang UDP hoặc kết nối riêng, không để vị trí cũ tích lại trong bộ đệm gửi (TCP_NOTSENT_LOWAT)Loại bỏ điểm gây mất gói (cáp, module quang, duplex, policer, theo dõi kết nối của tường lửa, MTU), chỉnh MSS, ring buffer và phân tán ngắt trên server, cấu hình phục hồi của kernel (RACK, tcp_mtu_probing)Lượng truyền lại tăng thêm (nstat), số lần zero window, bộ đếm drop và CRC của NIC và cổng switch
Vượt tick budget do CPU server bão hòa
Trước tiênĐội phát triển gameServer
Tối ưu tính toán tầm nhìn và broadcast, chia tick ra nhiều thread, chia nhỏ bản đồ và kênh đông người, chỉnh số worker thread cho vừa giới hạn CPU, ghi thời gian xử lý tick thành chỉ sốCPU hoặc instance có hiệu năng đơn nhân (xung nhịp) cao, cảnh báo mức sử dụng CPU theo từng core, kiểm tra CPU steal và CPU throttling của container, tách core xử lý ngắt khỏi core chạy thread tickThời gian xử lý tick, mức sử dụng CPU theo từng core, steal, số lần throttling (nr_throttled)
DB phản hồi chậm
Trước tiênĐội phát triển gameServerĐội hạ tầngThiết bị DB
Thiết kế query, index và transaction (ngắn gọn, thống nhất thứ tự khóa), gọi bất đồng bộ bên ngoài thread game, gộp truy vấn và cache, điều chỉnh kích thước connection pool và timeout chờTìm query chậm, kế hoạch thực thi và chờ lock rồi chia sẻ cho đội phát triển game, cấu hình checkpoint, replication và cập nhật thống kê, IOPS của storage, kiểm tra số server × kích thước pool có nằm trong số kết nối tối đa không, nâng cấp thiết bị DBLog query chậm, chờ lock, chờ kết nối DB, replication lag, IOPS
Không vào được ngay sau bảo trì
Trước tiênĐội phát triển gameServer
Không để thread nhận kết nối (vòng lặp accept) bị kẹt vì việc khác, tăng tham số backlog của listen, hệ thống hàng chờ đăng nhập, gộp query đăng nhập (loại bỏ N+1), giãn dần khoảng thử lại của client và rải ngẫu nhiênsomaxconn và SYN cookie của kernel, giới hạn phiên của tường lửa và bộ cân bằng tải, giới hạn conntrack và file descriptor của server, làm nóng cache DB, mở rộng server trước sự kiệnListenOverflows, mức dùng bảng phiên và conntrack, số query đăng nhập và thời gian chờ kết nối DB
Để yên thì mất kết nối
Trước tiênĐội phát triển gameClient
Client: gửi heartbeat với khoảng cách không quá một nửa idle timeout ngắn nhất (để dù một gói đến muộn hoặc bị mất, gói tiếp theo vẫn tới trước khi hết timeout), bị ngắt thì tự động kết nối lại. Server: phản hồi heartbeat, không nhận được trong một khoảng thời gian thì chủ động dọn kết nối trước, nối lại phiên bằng session token.Thu thập idle timeout của bộ cân bằng tải và tường lửa trên tuyến (mạng) và thời gian theo dõi kết nối của security group trên cloud (thiết bị server·OS) để chia sẻ cho đội phát triển game, tăng giá trị trên thiết bị của mình khi cần. Timeout của router nhà người chơi và CGNAT của nhà mạng thì không thay đổi đượcPhân bố thời gian nhàn rỗi của các kết nối bị ngắt (nếu dồn quanh một giá trị thì đó là thiết bị có timeout đó), loại mạng (di động, có dây)
Server bị đứng vào những giờ cố định
Trước tiênĐội phát triển gameServerĐội hạ tầngThiết bị server·OS
Rải ngẫu nhiên thời điểm của sự kiện đúng giờ, lưu dữ liệu, timer và cache hết hạn; chia nhỏ query batch để chạy từng ít một; chỉ định rõ loại GC có thời gian dừng ngắnRải giờ chạy cron, sao lưu, nén log và hạ mức ưu tiên I/O; sao lưu DB trên bản sao và rải đều checkpoint; kiểm tra burst credit của ổ đĩa; giới hạn tốc độ truyền bản sao lưuĐối chiếu thời điểm server bị đứng với lịch tác vụ (cron, sao lưu, batch, checkpoint), log GC
DDoS, lưu lượng tăng đột biến
Trước tiênĐội hạ tầngMạng
Chia sẻ đặc điểm lưu lượng game (cổng, kích thước gói, số gói mỗi giây) cho đội hạ tầng, giới hạn tần suất yêu cầu theo tài khoản và nhân vật, chặn sớm gói bất thườngChống DDoS (scrubbing) với quy tắc phù hợp lưu lượng game, ẩn địa chỉ server, giới hạn số gói mỗi giây của thiết bị, giới hạn theo IP phải tính đến IP dùng chung của nhà mạng và quán net (PC bang)Số gói mỗi giây, CPU và drop của thiết bị, tỷ lệ kết nối thất bại theo khu vực và nhà mạng (để phát hiện chặn nhầm)
Sự cố Wi-Fi hoặc PC của người chơi
Trước tiênBên ngoàiNgười chơi·nhà mạng·cloudĐội phát triển gameClient
Hiển thị trạng thái mạng trong game (ping, mất gói), tự điều chỉnh độ dài bộ đệm nội suy theo jitter, ghi loại mạng và mức sử dụng CPU của PC vào log lúc xảy ra lag, thông báo hướng dẫn như dùng dây mạngKhông tự sửa được. Nếu báo cáo dồn vào cùng một nhà mạng hoặc khu vực thì phân loại lại thành vấn đề đường truyềnThông tin đường truyền và thiết bị trong báo cáo, tỷ lệ báo cáo đến từ cùng một nhà mạng hoặc khu vực

Thông tin cần kèm khi chuyển giao

Đội phát triển game → đội hạ tầng

  • Thời điểm chính xác (đến từng giây, ghi rõ múi giờ) và thời gian kéo dài, hiện vẫn đang tiếp diễn hay không
  • ID server và kênh, phạm vi ảnh hưởng (một người, một nhà mạng, cả server) và số người bị ảnh hưởng (so với số người chơi đồng thời)
  • Tên và biểu hiện của triệu chứng: nếu mất kết nối thì thời gian nhàn rỗi trước khi bị ngắt, nếu đứng hình thì độ dài và chu kỳ lặp lại
  • IP, cổng, nhà mạng và khu vực của người gặp sự cố (nếu một trong nhiều tuyến bị lỗi thì phải có cả cổng mới phân biệt được), giao thức game dùng (TCP, UDP) và cổng của server
  • Chỉ số phía game: thời gian xử lý tick, phân bố ping và mất gói, số kết nối có truyền lại tăng, lý do mất kết nối (heartbeat quá hạn, kết nối bị từ chối (RST), v.v.)
  • Khoảng cách heartbeat đang dùng, thời gian server coi là không phản hồi, cách thử lại
  • Có triển khai hay thay đổi cấu hình gần đây không, các nguyên nhân đã kiểm tra và loại trừ

Đội hạ tầng → đội phát triển game

  • Chỉ số thiết bị và đường truyền cùng thời điểm (mức sử dụng, bộ đếm drop và lỗi, số phiên) và chỉ số OS server (ListenOverflows, mức dùng conntrack, CPU steal)
  • Giá trị timeout và giới hạn của các thiết bị trên tuyến: idle timeout của bộ cân bằng tải và tường lửa, thời gian theo dõi kết nối của security group, giới hạn số phiên và số gói mỗi giây
  • Lịch sử thay đổi thiết bị, đường truyền và các công việc đã lên lịch (thay thế, đổi cấu hình, sao lưu và cron, thông báo bảo trì của nhà mạng)
  • Số ticket đã gửi nhà mạng hoặc nhà cung cấp cloud và thời điểm dự kiến nhận phản hồi
  • Biện pháp tạm thời (đi đường vòng, nới giới hạn) và thời điểm gỡ bỏ
  • Chặng gây ra nguyên nhân, kết luận, kế hoạch ngăn tái diễn
  • Những việc cần phía game làm (khoảng cách heartbeat, cách thử lại, giới hạn số kết nối, v.v.)

Chung cho cả hai đội: chọn một người chịu trách nhiệm xử lý sự cố, ghi nhật ký theo thứ tự thời gian trong một kênh duy nhất và báo trước thời điểm cập nhật tiếp theo. Nếu phụ trách chính chuyển sang đội khác, chuyển giao luôn nhật ký này để không ai phải lặp lại các bước kiểm tra đã làm. Khi xong việc, dùng chính nhật ký đó để sửa phần phụ trách và việc cần làm trên thẻ nguyên nhân tương ứng.

Tiến trình game phía client

Đây chính là chương trình game chạy trên PC hoặc điện thoại của người chơi. Dù mạng hoàn hảo, nếu khung hình ở đây bị trễ thì màn hình vẫn giật khựng. Và khi mạng kém, game che được đến đâu cũng do tầng này quyết định.

Game lặp lại cùng một chuỗi việc khoảng 60 lần trong 1 giây: đọc input, xử lý các gói tin đã nhận, cập nhật trạng thái game thêm một bước, rồi vẽ màn hình. Mỗi vòng lặp như vậy là một khung hình; ở 60 FPS, mỗi khung hình có 16,7 ms (game điện thoại chạy 30 FPS thì là 33,3 ms). Một khung hình bị trễ thì màn hình dừng đúng chừng đó, rồi ở khung hình sau nhảy một lượt bù cho phần bị dồn.

Về mặt mạng, việc của client là “lấp chỗ thông tin còn thiếu”. Vị trí của người chơi khác được server gửi về cách quãng nên client phải vẽ nối khoảng giữa (nội suy); khi gói tin bị gián đoạn, client phải đoán để đối tượng tiếp tục di chuyển (ngoại suy); còn nhân vật của bạn thì được cho di chuyển trước mà không chờ server xác nhận (dự đoán). Cách các kỹ thuật này thất bại chính là dịch chuyển tức thời, kéo ngược và giật khựng.

So sánh

Client game giống như phòng điều khiển của một chương trình truyền hình trực tiếp. Khi ảnh từ hiện trường (server) gửi về cách quãng, phòng điều khiển ghép nối chúng thật mượt để trông như video. Ảnh về muộn thì không có gì để ghép nên hình đứng lại, còn nếu bản thân phòng điều khiển quá bận thì chương trình cũng bị gián đoạn.

Các nguyên nhân gây lag ở tầng này

Frame time vọt lên Frame hitch

Việc tính toán một khung hình mất thời gian gấp nhiều lần bình thường nên màn hình dừng lại trong chốc lát.

Vì sao: Hiệu ứng skill tăng đột biến, spawn hàng loạt, cập nhật toàn bộ UI dồn vào cùng một khung hình → Dẫn đến: Không xong kịp trong 16,7 ms, mất tới 50–300 ms → Trên màn hình: Màn hình khựng lại, sang khung hình sau mọi nhân vật cùng nhảy tới vị trí mới một lượt

Triệu chứng: Giật khựng, Đứng hình · Phụ trách chính Phát triển client (Đội phát triển game)

Thu gom rác (GC) phía client Client GC (Unity C#, Unreal, Lua)

Trong lúc thu hồi bộ nhớ đã dùng xong (rác), cả game dừng lại. Đặc trưng là giật khựng theo khoảng cách đều đặn.

Vì sao: Mỗi khung hình đều tạo rồi bỏ các chuỗi, mảng, list tạm → Dẫn đến: Rác dồn lại thì GC dừng main thread để thu hồi → Trên màn hình: Cứ vài giây đến vài chục giây lại giật khựng đều đặn

Triệu chứng: Giật khựng, Đứng hình · Phụ trách chính Phát triển client (Đội phát triển game)

Tải đồng bộ trên main thread và biên dịch shader Synchronous asset load, shader compile

Ngay trước khi vẽ khu vực, quái hay hiệu ứng lần đầu xuất hiện, game phải đọc file và tạo shader nên bị dừng.

Vì sao: Vào khu vực mới, skill, trang bị hoặc quái lần đầu xuất hiện → Dẫn đến: Main thread phải chờ đọc file và biên dịch shader → Trên màn hình: Chỉ đứng hình 0,1–1 giây ở lần đầu, từ lần thứ hai trở đi thì bình thường

Triệu chứng: Đứng hình, Giật khựng · Phụ trách chính Phát triển client (Đội phát triển game)

Ổ lưu trữ chậm khiến streaming asset không theo kịp Slow storage stalls asset streaming

Trên ổ lưu trữ chậm như HDD, tốc độ đọc texture và model của thế giới mở không theo kịp tốc độ di chuyển, nên đối tượng hiện ra muộn hoặc game giật vì phải chờ đọc xong.

Vì sao: Di chuyển nhanh bằng thú cưỡi hoặc teleport, hay đi vào nơi đông người, nên cần cùng lúc nhiều texture và model mới → Dẫn đến: Ổ lưu trữ chậm như HDD không đọc kịp tốc độ cần thiết nên yêu cầu đọc dồn lại, một số phần loading khiến main thread phải chờ tới khi xong → Trên màn hình: Texture mờ một lúc, nhà cửa và nhân vật hiện ra muộn; lúc chờ đọc thì giật khựng hoặc đứng hình

Triệu chứng: Không hiển thị·đối tượng ma, Giật khựng, Đứng hình · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Bên ngoài (Bên ngoài)

Tải render khi đông người Render/animation cost of crowds

Khi hàng trăm người cùng hiện trên một màn hình như lúc công thành hay đánh world boss, riêng chi phí vẽ đã vượt quá sức máy.

Vì sao: Hàng trăm người và hiệu ứng chồng lên nhau trên một màn hình → Dẫn đến: Chi phí hoạt ảnh, bóng đổ, bảng tên, hiệu ứng tăng theo số người → Trên màn hình: FPS tụt từ 60 → 15, mọi chuyển động đều giật khựng và thao tác cũng bị trễ

Triệu chứng: Giật khựng, Trễ thao tác · Phụ trách chính Phát triển client (Đội phát triển game)

Nghẽn xử lý gói tin trên main thread Network processing on the main thread

Nếu mỗi khung hình chỉ xử lý một lượng gói tin cố định, số gói dồn tới sẽ liên tục bị đẩy sang khung hình sau.

Vì sao: Ở nơi đông người, mỗi giây có hàng nghìn bản cập nhật đổ về → Dẫn đến: Main thread chạm giới hạn xử lý mỗi khung hình nên đọc không hết → Trên màn hình: Chuyển động của người khác hiện ra ngày càng trễ và dồn cục

Triệu chứng: Tua nhanh, Trễ thao tác · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game)

Bộ đệm nội suy không có hoặc quá ngắn Missing/short interpolation buffer

Nếu vẽ ngay khi nhận gói tin từ server, jitter (độ dao động của khoảng cách giữa các lần gói tin đến) lộ nguyên trên màn hình.

Vì sao: Vẽ ngay vị trí vừa nhận, hoặc bộ đệm ngắn hơn jitter → Dẫn đến: Gói tới muộn bao lâu thì dừng bấy lâu, gói dồn tới bao nhiêu thì nhảy bấy nhiêu → Trên màn hình: Nhân vật khác di chuyển khựng khựng

Triệu chứng: Giật khựng · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game)

Ngoại suy quá mức (dead reckoning) Over-extrapolation / dead reckoning

Trong lúc không có gói tin, client cho đối tượng tiếp tục di chuyển theo vận tốc cuối cùng, rồi khi biết là sai thì kéo lại.

Vì sao: Không nhận được gói tin nên tiếp tục cho di chuyển theo hướng và vận tốc cuối cùng → Dẫn đến: Trên thực tế đối thủ đã dừng lại hoặc đổi hướng → Trên màn hình: Nhân vật đối thủ đi một đoạn dài rồi vụt về vị trí thật, hoặc đi xuyên tường. Nếu khoảng cách gói tin đến lúc dài lúc ngắn, nhân vật cứ vượt lên trước rồi bị kéo lại, trông như đang rung

Triệu chứng: Dịch chuyển tức thời, Giật khựng · Phụ trách chính Phát triển client (Đội phát triển game)

Dự đoán phía client sai lệch Prediction mismatch / reconciliation

Client của bạn đã cho nhân vật di chuyển trước, nhưng nếu server tính ra kết quả khác thì nhân vật của bạn bị kéo đi.

Vì sao: Client cho di chuyển trước khi server xác nhận (dự đoán) → Dẫn đến: Server tính va chạm, tốc độ di chuyển, buff theo cách khác, hoặc không nhận được lệnh → Trên màn hình: Khi xác nhận về, nhân vật của bạn bị kéo ngược về sau

Triệu chứng: Kéo ngược · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game)

Fixed timestep chạy bù mất kiểm soát Fixed-timestep catch-up / spiral of death

Sau một lần dừng, game dồn phần tính toán bị tồn lại để chạy bù, và chính phần tính toán đó lại làm game chậm tiếp.

Vì sao: Mô phỏng game chạy theo bước thời gian cố định, rồi bị dừng một lần → Dẫn đến: Dồn các bước bị tồn vào một khung hình để tính → Trên màn hình: Các khung hình dài nối đuôi nhau gây giật, hoặc chạm giới hạn khiến cả thế giới chậm lại

Triệu chứng: Giật khựng, Tua nhanh, Quay chậm · Phụ trách chính Phát triển client (Đội phát triển game)

Sai lệch đồng bộ đồng hồ Clock sync error

Nếu giờ server mà client ước tính bị sai, thời điểm nội suy và việc phán định hồi chiêu sẽ lệch.

Vì sao: Chỉ đồng bộ giờ server một lần lúc kết nối, ping thay đổi cũng để nguyên → Dẫn đến: Thời điểm nội suy và thời điểm hết hồi chiêu lệch với server → Trên màn hình: Đối thủ thỉnh thoảng khựng lại, hết hồi chiêu rồi mà skill vẫn bị từ chối

Triệu chứng: Giật khựng, Nuốt thao tác·rollback · Phụ trách chính Phát triển client (Đội phát triển game)

Mất độ chính xác thời gian kiểu float Float time precision loss on long sessions

Nếu game lưu thời gian bằng kiểu số thực độ chính xác thấp (float), game bật càng lâu thì độ phân giải thời gian (khoảng chênh nhỏ nhất còn phân biệt được) càng kém, khiến chuyển động và hiệu ứng bị rung.

Vì sao: Cộng dồn thời gian kể từ lúc bật game vào biến float, hoặc truyền thẳng giá trị đó cho shader → Dẫn đến: Bật càng lâu thì khoảng chênh nhỏ nhất mà float biểu diễn được càng lớn → Trên màn hình: Chỉ client bật liên tục mấy ngày mới bị rung nhân vật, hoạt ảnh và hiệu ứng chuyển động; khởi động lại là hết

Triệu chứng: Giật khựng · Phụ trách chính Phát triển client (Đội phát triển game)

V-Sync và hàng đợi render V-Sync, render queue

GPU xếp vài khung hình đã vẽ vào hàng đợi rồi mới đẩy ra theo chu kỳ của màn hình, và trong lúc đó thao tác bị trễ.

Vì sao: Driver đồ họa xếp trước 1–3 khung hình vào hàng đợi → Dẫn đến: Thao tác mất thêm chừng ấy thời gian mới hiện lên màn hình → Trên màn hình: Ping thấp nhưng điều khiển thấy nặng và ì

Triệu chứng: Trễ thao tác, Giật khựng · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Bên ngoài (Bên ngoài)

Rò rỉ bộ nhớ phía client Client memory leak

Game bật càng lâu thì bộ nhớ dùng càng tăng, game chậm dần rồi cuối cùng bị tắt cưỡng bức.

Vì sao: Texture, UI, hiệu ứng không được giải phóng khi chuyển qua lại giữa các bản đồ → Dẫn đến: GC chạy dày hơn, OS thiếu bộ nhớ nên phải dùng swap → Trên màn hình: Sau vài giờ chơi, game giật khựng ngày càng nhiều rồi bị tắt cưỡng bức (người chơi thấy giống mất kết nối)

Triệu chứng: Giật khựng, Mất kết nối · Phụ trách chính Phát triển client (Đội phát triển game)

Client bị crash Client crash

Game tắt vì một lỗi không được xử lý. Người chơi thấy giống mất kết nối, nhưng server vẫn bình thường.

Vì sao: Tham chiếu null, thiếu bộ nhớ, lỗi driver đồ họa → Dẫn đến: Tiến trình game bị kết thúc đột ngột → Trên màn hình: Báo cáo “bị văng game”. Cùng lúc đó người khác vẫn chơi bình thường

Triệu chứng: Mất kết nối · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Bên ngoài (Bên ngoài)

Kiểm tra của module bảo mật game (anti-cheat) Anti-cheat scan and heartbeat

Module bảo mật chạy cùng game để chống hack sẽ kiểm tra định kỳ. Nếu lần kiểm tra nặng, hoặc heartbeat (tín hiệu định kỳ báo vẫn còn sống) trao đổi với server bảo mật bị trễ, game sẽ giật khựng hoặc mất kết nối.

Vì sao: Module bảo mật định kỳ quét bộ nhớ game, các chương trình đang chạy và driver → Dẫn đến: Trong lúc quét, game thread bị dừng, hoặc heartbeat không gửi đi kịp → Trên màn hình: Khựng theo khoảng cách đều, nặng thì mất kết nối kèm thông báo lỗi bảo mật

Triệu chứng: Giật khựng, Đứng hình, Mất kết nối · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game)

OS và thiết bị phía client

Game chạy trên Windows, Android, iOS và dùng chung CPU, bộ nhớ, mạng với các chương trình khác. Nếu hệ điều hành cấp CPU cho game muộn, hạ tốc độ để tiết kiệm pin, hoặc tạm dừng ứng dụng chạy nền, lag sẽ xuất hiện.

Bộ lập lịch (scheduler, phần quyết định đến lượt chương trình nào dùng CPU) của hệ điều hành (OS) chia thời gian CPU cho các chương trình. Game, phần mềm diệt virus, trình duyệt, chương trình cập nhật đều chờ “đến lượt mình”, và OS luân phiên cấp core cho từng chương trình, mỗi lượt từ vài ms đến vài chục ms (time slice). OS có dành mức ưu tiên cao hơn một chút cho game đang mở phía trước (foreground), nhưng khi việc nhiều hơn số core thì game cũng phải chờ, và khoảng chờ đó làm khung hình bị trễ.

Mạng cũng đi qua OS. Gói tin do card mạng hay chip Wi-Fi nhận được sẽ nằm trong bộ đệm nhận của driver và OS, chờ đến khi game lấy ra. Game bận nên lấy muộn thì bộ đệm bị tràn, lấy dồn một lượt thì thành tua nhanh. Trên mobile, điều đặc biệt quan trọng là OS chuyển kết nối không dây sang trạng thái tiết kiệm điện để giữ pin và thường xuyên tạm dừng chính ứng dụng.

So sánh

OS giống như bếp trưởng bắt nhiều đầu bếp dùng chung một căn bếp duy nhất. Dù game đang nấu món gấp, nếu đầu bếp tên “quét virus” chiếm bếp lửa thì game vẫn phải chờ. Khi căn bếp quá nóng (tỏa nhiệt), bếp trưởng còn vặn nhỏ lửa.

Các nguyên nhân gây lag ở tầng này

Tiến trình chạy nền chiếm giữ CPU Background CPU contention

Khi việc quét virus, Windows Update, phần mềm livestream hay video trên trình duyệt chiếm các core, game thread không được cấp CPU và phải chờ.

Vì sao: Chương trình khác chiếm giữ core CPU trong thời gian dài → Dẫn đến: Game thread phải chờ được lập lịch → Trên màn hình: Khung hình bị trễ, việc xử lý gói tin đã nhận cũng trễ theo

Triệu chứng: Giật khựng, Tua nhanh · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Chế độ tiết kiệm điện và bóp xung do nhiệt Power saving, thermal throttling

Chế độ pin của laptop, chế độ tiết kiệm pin của điện thoại hay máy nóng lên đều làm tốc độ CPU, GPU giảm. Đặc trưng của quá nhiệt là lúc đầu vẫn ổn, chơi một lúc lâu mới bắt đầu chậm.

Vì sao: Đang ở chế độ pin hoặc tiết kiệm điện, hoặc máy nóng lên → Dẫn đến: Xung nhịp CPU, GPU bị hạ 30–50% tùy thiết bị → Trên màn hình: Với chế độ tiết kiệm điện thì ngay khi bật game, với quá nhiệt thì sau khi chơi vài phút đến khoảng 20 phút, FPS tụt và bị giật khựng

Triệu chứng: Giật khựng, Trễ thao tác · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Độ phân giải timer Timer resolution (Windows 15.6ms)

Timer mặc định của Windows có bước 15,6 ms, nên lệnh “chỉ nghỉ 1 ms” thực tế kéo dài tới chu kỳ timer kế tiếp, lâu nhất tới 15,6 ms.

Vì sao: Giới hạn khung hình và gửi gói tin được cài đặt bằng Sleep (chờ một chút) → Dẫn đến: OS chỉ đánh thức theo bước 15,6 ms → Trên màn hình: Khoảng cách giữa các khung hình và giữa các lần gửi input lúc dài lúc ngắn

Triệu chứng: Giật khựng · Phụ trách chính Phát triển client (Đội phát triển game)

Ứng dụng di động chuyển xuống chạy nền App suspended in background

Khi bạn tạm chuyển ra khỏi game để xem thông báo, vài giây sau OS tạm dừng (suspend) ứng dụng, và trong lúc đó server ngắt kết nối của bạn.

Vì sao: Chuyển ra khỏi game để xem tin nhắn hoặc nghe điện thoại → Dẫn đến: Engine game dừng xử lý game, OS cũng nhanh chóng dừng ứng dụng và kết nối mạng → Trên màn hình: Quay lại thì đã mất kết nối, phải kết nối lại

Triệu chứng: Mất kết nối · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game)

Chuyển đổi Wi-Fi ↔ LTE hoặc 5G Network switch changes IP

Khi bạn ra khỏi nhà, Wi-Fi mất và máy chuyển sang LTE hoặc 5G, địa chỉ IP của bạn thay đổi nên kết nối hiện có không còn dùng được.

Vì sao: Sóng Wi-Fi yếu đi nên máy chuyển sang mạng di động → Dẫn đến: Địa chỉ IP của bạn đổi, nên kết nối đã thiết lập bằng địa chỉ cũ không trao đổi dữ liệu được nữa → Trên màn hình: Đứng hình một chút rồi mất kết nối hoặc phải kết nối lại

Triệu chứng: Đứng hình, Mất kết nối · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game), Hạ tầng mạng (Đội hạ tầng)

Phần mềm bảo mật kiểm tra gói tin Antivirus / firewall inspection

Khi phần mềm diệt virus hay tường lửa kiểm tra mọi gói tin, độ trễ tăng lên; nếu quá tay, chúng còn nhầm game là tấn công và chặn lại.

Vì sao: Phần mềm bảo mật kiểm tra từng gói tin gửi và nhận → Dẫn đến: Mỗi gói bị cộng thêm độ trễ, kiểm tra không kịp thì gói bị bỏ → Trên màn hình: Ping nhảy thất thường hoặc bị chặn kết nối

Triệu chứng: Giật khựng, Không vào được·kẹt loading · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Tràn bộ đệm nhận Socket receive buffer overflow

Khi game bận và lấy gói tin ra khỏi socket (giao diện gửi nhận qua mạng do OS cung cấp) chậm, bộ đệm của OS bị tràn.

Vì sao: Khung hình bị trễ nên game đọc socket muộn → Dẫn đến: Bộ đệm nhận của OS đầy: với UDP thì gói bị bỏ, với TCP thì cửa sổ nhận bị thu hẹp khiến bên gửi phải dừng → Trên màn hình: Dịch chuyển tức thời (UDP) hoặc tua nhanh (TCP)

Triệu chứng: Dịch chuyển tức thời, Tua nhanh · Phụ trách chính Phát triển client (Đội phát triển game)

Thiếu bộ nhớ và swap phía client Paging / swap on client

Khi mở vài chục tab trình duyệt cùng lúc với game, OS đẩy một phần bộ nhớ của game xuống ổ đĩa.

Vì sao: Tổng RAM không đủ → Dẫn đến: OS chuyển phần bộ nhớ game chưa dùng tới xuống ổ đĩa → Trên màn hình: Lúc cần dùng lại phần đó, game đứng hình vài chục đến vài trăm ms tùy ổ lưu trữ

Triệu chứng: Đứng hình, Giật khựng · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Thiếu bộ nhớ đồ họa (VRAM) VRAM over-commit

Nếu tùy chọn đồ họa cần nhiều bộ nhớ hơn bộ nhớ của card đồ họa, OS phải đẩy texture ra bộ nhớ của PC rồi lấy lại, gây giật khựng.

Vì sao: Tùy chọn texture cao, đủ loại trang bị và hiệu ứng ở nơi đông người làm đầy bộ nhớ card đồ họa → Dẫn đến: OS chuyển texture chưa dùng tới sang bộ nhớ PC, khi cần lại lấy về qua bus PCIe chậm → Trên màn hình: Mỗi khi có cảnh mới hoặc nhân vật mới xuất hiện thì khựng, texture mờ một lúc

Triệu chứng: Giật khựng, Đứng hình · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Bên ngoài (Bên ngoài)

Wi-Fi quét nền Periodic Wi-Fi background scan

OS định kỳ chuyển qua các kênh để dò Wi-Fi xung quanh, và trong lúc đó việc truyền dữ liệu tạm dừng.

Vì sao: OS hoặc driver dò tìm Wi-Fi xung quanh theo chu kỳ → Dẫn đến: Trong lúc dò, việc gửi nhận tạm dừng → Trên màn hình: Ping vọt lên theo khoảng cách đều chính xác (ví dụ cứ 60 giây một lần)

Triệu chứng: Giật khựng, Dịch chuyển tức thời · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Tiết kiệm điện NIC và lỗi driver NIC power saving, driver bugs

Nếu card mạng LAN hoặc chip Wi-Fi vào trạng thái tiết kiệm điện giữa các gói tin, việc kích hoạt lại sẽ tốn thời gian.

Vì sao: Tính năng tiết kiệm điện của thiết bị mạng đang bật hoặc driver đã cũ → Dẫn đến: Trễ khi đánh thức (wake-up), thỉnh thoảng thiết bị tự khởi động lại → Trên màn hình: Độ trễ thất thường, đôi khi đứng hình vài giây

Triệu chứng: Giật khựng, Đứng hình · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Ứng dụng khác trên cùng thiết bị chiếm giữ băng thông Other apps saturating the link

Khi đồng bộ cloud, tải file dung lượng lớn hay tải bản cập nhật game chạy trên cùng PC, gói tin của game phải chờ trong hàng đợi.

Vì sao: Ứng dụng khác dùng tối đa chiều tải lên hoặc tải xuống → Dẫn đến: Gói tin game dồn vào hàng đợi của PC và router → Trên màn hình: Ping tăng vọt, trễ thao tác, tua nhanh

Triệu chứng: Trễ thao tác, Tua nhanh · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Giới hạn xử lý khi cửa sổ bị thu nhỏ hoặc mất focus Minimized / unfocused window throttling

Khi bạn chuyển sang cửa sổ khác hoặc thu nhỏ game, cả game lẫn Windows đều cho game chạy chậm lại để tiết kiệm điện. Lúc quay lại, gói tin tồn đọng dồn tới một lượt, hoặc kết nối đã bị ngắt.

Vì sao: Nhấn Alt+Tab sang cửa sổ khác hoặc thu nhỏ game → Dẫn đến: Trong lúc không hiển thị, game hạ FPS xuống rất thấp hoặc dừng hẳn, Windows cũng hạ mức ưu tiên của chương trình không hiển thị → Trên màn hình: Vừa quay lại thì tua nhanh, nếu thu nhỏ lâu thì mất kết nối

Triệu chứng: Tua nhanh, Giật khựng, Mất kết nối · Phụ trách chính Phát triển client (Đội phát triển game)

Phần mềm overlay can thiệp vào game Overlays and screen hooks

Phần mềm nhắn tin, launcher, quay màn hình, hiển thị FPS chen vào quá trình render của game (hooking) để vẽ UI của chúng đè lên màn hình game. Mỗi khung hình phải làm thêm việc, và đôi khi xung đột với game gây khựng hoặc làm game bị tắt đột ngột.

Vì sao: Overlay của phần mềm nhắn tin, launcher game, công cụ card đồ họa hoặc phần mềm quay màn hình đang bật → Dẫn đến: Mỗi lần khung hình được đẩy ra màn hình, overlay chen vào để vẽ đè UI của nó → Trên màn hình: Khung hình trễ đi một chút, lúc có thông báo hiện lên thì khựng, hoặc lỗi đồ họa, game bị tắt đột ngột (người chơi thấy giống mất kết nối)

Triệu chứng: Giật khựng, Đứng hình, Mất kết nối · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Độ trễ của màn hình, thiết bị nhập và tạo khung hình Display, input device and frame generation latency

Nếu ping bình thường mà điều khiển vẫn thấy nặng, có thể phần xử lý hình ảnh của TV, tay cầm không dây hoặc tính năng tạo khung hình đang cộng thêm độ trễ giữa thao tác và màn hình.

Vì sao: Chế độ game của TV đang tắt, dùng tay cầm Bluetooth hoặc không dây, hoặc bật tạo khung hình (frame generation của DLSS, FSR) → Dẫn đến: TV xuất khung hình muộn vì bận xử lý chất lượng hình ảnh, input không dây tới muộn do chu kỳ truyền và nhiễu, còn tạo khung hình phải chờ khung hình kế tiếp rồi mới tạo khung hình chen giữa → Trên màn hình: Ping và FPS đều đẹp nhưng bấm xong phải một lúc mới thấy trên màn hình, tức là trễ thao tác

Triệu chứng: Trễ thao tác · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Mạng gia đình: Wi-Fi, router, mạng di động

Đây là vài mét cuối cùng trước khi gói tin rời khỏi nhà. Quãng đường ngắn nhưng khá nhiều báo cáo lag bắt nguồn từ đây, vì Wi-Fi dùng chung một kênh không dây cho nhiều thiết bị, còn router đẩy lưu lượng của cả nhà ra ngoài qua một hàng đợi duy nhất.

Wi-Fi dùng chung kênh không dây (dải tần) với router nhà hàng xóm, và băng tần 2,4 GHz còn trùng với Bluetooth và lò vi sóng. Khi phát bị va chạm, thiết bị nghỉ một chút rồi phát lại; các lần truyền lại này dồn lên khiến gói tin đến lúc nhanh lúc chậm. Ping trung bình trông vẫn ổn nhưng từng lúc lại vọt lên, đó là biểu hiện điển hình của Wi-Fi.

Router là thiết bị mà mọi thiết bị trong nhà bắt buộc phải đi qua để ra Internet. Khi gửi nhiều hơn tốc độ mà đường truyền Internet tiếp nhận được, hàng đợi sẽ hình thành bên trong router hoặc modem; thiết bị không có tính năng quản lý hàng đợi (SQM) để hàng đợi này dài tới mức hàng trăm ms. Router đắt tiền mà tắt tính năng này cũng vậy. Ngay khi đứa em trong nhà tải video lên, gói tin game cũng phải xếp cuối hàng đợi đó. Hiện tượng này gọi là bufferbloat.

Router còn ghi mỗi kết nối “thiết bị bên trong ↔ server bên ngoài” vào bảng NAT, và nếu một thời gian không có gói tin qua lại thì xóa mục đó khỏi bảng. Đây là nguyên nhân phổ biến của hiện tượng để yên một lúc thì mất kết nối. Với mạng di động, còn có thêm việc chuyển trạm phát sóng, trạng thái tiết kiệm điện của sóng vô tuyến và sóng yếu.

So sánh

Router giống như cổng ra vào duy nhất của một khu chung cư. Khi xe tải chuyển nhà (tải video lên) xếp hàng dài, ngay cả xe máy giao hàng hỏa tốc (gói tin game) cũng phải chờ sau xe tải. Router thông minh (SQM) sẽ mở riêng một làn cho xe giao hàng hỏa tốc.

Các nguyên nhân gây lag ở tầng này

Nhiễu và sóng Wi-Fi yếu Wi-Fi interference, weak signal

Khi sóng yếu hoặc bị nhiễu, đoạn không dây phải gửi lại nhiều lần nên thời điểm gói tin đến lúc nhanh lúc chậm.

Vì sao: Chất lượng sóng giảm do tường, khoảng cách, lò vi sóng, Bluetooth, router nhà hàng xóm → Dẫn đến: Truyền thất bại ở đoạn không dây → truyền lại nhiều lần → Trên màn hình: Gói tin đến lúc nhanh lúc chậm (jitter) nên nhân vật khựng khựng, nặng thì mất gói và dịch chuyển tức thời

Triệu chứng: Giật khựng, Dịch chuyển tức thời, Kéo ngược · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Kênh Wi-Fi bị nghẽn Crowded Wi-Fi channel

Ở nơi có hàng chục router như chung cư, các thiết bị phải chia nhau cùng một kênh nên phải chờ tới lượt truyền.

Vì sao: Hàng chục router dùng cùng một kênh 2,4 GHz → Dẫn đến: Muốn truyền thì phải chờ thiết bị khác truyền xong và kênh trống → Trên màn hình: Buổi tối khi mọi người về nhà, jitter (độ dao động của khoảng cách giữa các lần gói tin đến) tăng lên gây giật khựng

Triệu chứng: Giật khựng, Trễ thao tác · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Bufferbloat (hàng đợi của router) Bufferbloat

Khi ai đó trong nhà tải video lên hoặc tải file lớn xuống, hàng đợi của router dồn lượng gói tin tương đương hàng trăm ms, và gói tin game cũng phải chờ phía sau.

Vì sao: Người nhà tải video lên hoặc sao lưu lên cloud, bạn đang livestream, hoặc tải file dung lượng lớn làm đầy đường truyền → Dẫn đến: Router hoặc modem giữ các gói bị dư trong một hàng đợi lớn → Trên màn hình: Gói tin game cũng phải chờ cuối hàng đợi nên ping tăng vọt lên hàng trăm ms

Triệu chứng: Trễ thao tác, Tua nhanh, Dịch chuyển tức thời · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Ánh xạ NAT hết hạn NAT mapping timeout

Router xóa khỏi bảng NAT các kết nối nhàn rỗi không có gói tin qua lại trong một thời gian. Đây là nguyên nhân phổ biến khiến người chơi đứng yên một lúc, vừa di chuyển là mất kết nối.

Vì sao: Router ghi kết nối “thiết bị bên trong ↔ server bên ngoài” vào bảng NAT (bảng chuyển đổi địa chỉ) → Dẫn đến: Không có gói tin trong một thời gian thì bị xóa khỏi bảng (với UDP thường là 30–120 giây) → Trên màn hình: Gói tin từ server không vào được trong nhà nên mất kết nối

Triệu chứng: Mất kết nối · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game)

Router yếu hoặc quá nhiệt Router CPU / session table exhaustion

Khi một router giá rẻ phải gánh hàng chục thiết bị và hàng nghìn kết nối, bản thân router không xử lý nổi.

Vì sao: Hàng chục thiết bị, P2P và torrent mở hàng nghìn kết nối → Dẫn đến: CPU và bảng phiên của router bị bão hòa → Trên màn hình: Xử lý gói tin bị trễ, mất gói, kết nối mới thất bại

Triệu chứng: Giật khựng, Không vào được·kẹt loading, Mất kết nối · Phụ trách chính Bên ngoài (Bên ngoài)

Handover trạm phát sóng (khi đang di chuyển) Cellular handover

Khi di chuyển bằng xe buýt hay tàu điện ngầm, kết nối bị gián đoạn trong lúc máy đổi trạm phát sóng.

Vì sao: Di chuyển nên trạm phát sóng đang kết nối thay đổi → Dẫn đến: Thường chỉ gián đoạn vài chục ms, nhưng nếu sóng kém khiến chuyển trạm thất bại thì kết nối có thể bị ngắt vài trăm ms đến vài giây → Trên màn hình: Đứng hình rồi dịch chuyển tức thời, lâu thì mất kết nối

Triệu chứng: Đứng hình, Dịch chuyển tức thời, Mất kết nối · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game), Phát triển server (Đội phát triển game)

Trễ chuyển trạng thái RRC (chế độ tiết kiệm điện của mạng di động) Radio state promotion (RRC)

Khi không có dữ liệu trong một lúc, điện thoại hạ kết nối sóng xuống trạng thái tiêu thụ điện thấp, và đến gói tin kế tiếp phải kích hoạt lại nên bị trễ.

Vì sao: Không có dữ liệu một lúc thì điện thoại chuyển kết nối sóng sang trạng thái tiết kiệm điện → Dẫn đến: Muốn gửi gói tiếp theo phải kích hoạt lại kết nối → Trên màn hình: Riêng thao tác đầu tiên sau một lúc đứng yên bị trễ rõ rệt

Triệu chứng: Trễ thao tác · Phụ trách chính Phát triển client (Đội phát triển game)

Sóng di động yếu hoặc vùng lõm sóng Weak cellular signal

Trong thang máy, tầng hầm hay sâu bên trong tòa nhà, số lần truyền lại tăng, tốc độ giảm và cuối cùng mất kết nối.

Vì sao: Di chuyển vào nơi sóng yếu → Dẫn đến: Truyền lại trên đoạn không dây tăng, tốc độ giảm, mất sóng chốc lát → Trên màn hình: Jitter và mất gói gây giật khựng, dịch chuyển tức thời, cuối cùng mất kết nối

Triệu chứng: Giật khựng, Dịch chuyển tức thời, Mất kết nối · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Chuyển qua lại 5G↔LTE liên tục (vùng rìa phủ sóng 5G) 5G NSA / LTE switching

Ở trong tòa nhà có sóng 5G yếu hoặc vùng rìa phủ sóng 5G, điện thoại liên tục chuyển qua lại giữa 5G và LTE, và mỗi lần chuyển ping lại vọt lên hoặc kết nối bị ngắt chốc lát.

Vì sao: Đang ở nơi sóng 5G lúc có lúc không (trong tòa nhà, rìa vùng phủ 5G) → Dẫn đến: Điện thoại liên tục chuyển giữa 5G và LTE, mỗi lần chuyển có một khoảng gián đoạn ngắn → Trên màn hình: Dù đứng yên ping vẫn vọt lên bất thường, thỉnh thoảng đứng hình hoặc dịch chuyển tức thời

Triệu chứng: Giật khựng, Dịch chuyển tức thời, Đứng hình · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Giới hạn của Wi-Fi công cộng và mạng công ty Captive portal, restrictive network

Trang đăng nhập của Wi-Fi quán cà phê hoặc tường lửa công ty chặn kết nối của game.

Vì sao: Chưa xác thực ở trang đăng nhập, hoặc tường lửa chặn cổng game hay UDP → Dẫn đến: Bị chặn ngay từ lần thử kết nối, hoặc chỉ một phần đi qua được → Trên màn hình: Không vào được, hoặc đăng nhập được nhưng không vào được game

Triệu chứng: Không vào được·kẹt loading · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game), Phát triển server (Đội phát triển game)

Đường truyền Internet: mạng nhà mạng và chặng đường dài

Rời khỏi nhà, gói tin đi qua mạng của nhà mạng, các điểm kết nối giữa nhiều nhà mạng, đôi khi cả cáp quang biển, rồi mới tới trung tâm dữ liệu đặt server. Độ trễ ở chặng này phần lớn do khoảng cách và việc chọn tuyến (routing) quyết định, và nhiều khi công ty game không tự sửa được.

Ánh sáng đi trong cáp quang khoảng 200.000 km trong 1 giây. Với server cách 1.000 km, một lượt khứ hồi mất tối thiểu 10 ms, và chừng nào tín hiệu còn đi bằng cáp quang thì dù nâng cấp server hay thiết bị đến đâu cũng không giảm được con số này. Gói tin thực tế không đi đường thẳng mà vòng theo các điểm kết nối giữa các nhà mạng (peering), nên thường mất 1,5–2 lần giá trị lý thuyết. Những chặng hầu như không có tuyến cáp lớn chạy theo đường thẳng, như Hàn Quốc–châu Âu, phải vòng qua Đông Nam Á và kênh Suez hoặc qua Mỹ, nên lên tới 2,5–3 lần (khứ hồi khoảng 230–270 ms).

Vấn đề là tuyến đường này thay đổi theo thời gian và tình huống. Khoảng 9–11 giờ tối, ai cũng xem video nên các điểm kết nối giữa các nhà mạng dễ bị nghẽn; khi thông tin định tuyến (BGP) thay đổi, gói tin có thể không tới được đích trong vài giây đến vài chục giây (hiếm khi vài phút); khi cáp quang biển bị đứt, lưu lượng phải đi vòng đường xa trong nhiều tuần. Nếu lag chỉ xảy ra “với người dùng một nhà mạng”, “chỉ vào buổi tối” hay “chỉ khi ở nước ngoài”, hãy nghi tầng này trước.

So sánh

Mạng của nhà mạng giống như hệ thống đường cao tốc. Đường từ Seoul đi Busan dù không kẹt vẫn tốn thời gian tương ứng với quãng đường; trạm thu phí (điểm peering) kẹt vào giờ tan tầm; còn khi có tai nạn thì ứng dụng dẫn đường chỉ lối đi vòng thật xa.

Các nguyên nhân gây lag ở tầng này

Độ trễ lan truyền (khoảng cách vật lý) Propagation delay

Ngay cả ánh sáng trong cáp quang cũng chỉ đi được khoảng 200.000 km trong 1 giây. Server ở xa thì dù tốt đến đâu vẫn chậm.

Vì sao: Server ở xa (server nước ngoài, ở châu lục khác) → Dẫn đến: Thời gian khứ hồi tăng theo khoảng cách (tối thiểu 10 ms cho mỗi 1.000 km) → Trên màn hình: Mọi hành động đều bị trễ thao tác ở một mức cố định, chịu bất lợi khi phán định

Triệu chứng: Trễ thao tác · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Hạ tầng mạng (Đội hạ tầng), Phát triển server (Đội phát triển game)

Internet vệ tinh (quỹ đạo thấp, địa tĩnh) Satellite internet (LEO, GEO)

Với Internet vệ tinh, sóng phải đi lên vũ trụ rồi quay về. Vệ tinh địa tĩnh chỉ riêng thời gian khứ hồi đã hơn 0,5 giây. Vệ tinh quỹ đạo thấp như Starlink bình thường thì nhanh, nhưng vào lúc tuyến đường được phân lại, độ trễ dao động và đôi khi kết nối đứt quãng trong chốc lát.

Vì sao: Kết nối bằng Internet vệ tinh địa tĩnh hoặc quỹ đạo thấp, hoặc bằng Wi-Fi trên máy bay dùng vệ tinh, khi ở nhà, trên tàu hay trên máy bay → Dẫn đến: Vệ tinh địa tĩnh ở độ cao khoảng 36.000 km nên bản thân quãng đường đi và về đã dài; vệ tinh quỹ đạo thấp phân lại tuyến thiết bị đầu cuối–vệ tinh–trạm mặt đất theo chu kỳ ngắn, và vào lúc đó độ trễ tăng, mất gói trong chốc lát → Trên màn hình: Vệ tinh địa tĩnh gây trễ thao tác lớn ở mọi hành động; vệ tinh quỹ đạo thấp bình thường vẫn ổn nhưng cứ cách một khoảng đều lại giật khựng hoặc dịch chuyển tức thời

Triệu chứng: Trễ thao tác, Giật khựng, Dịch chuyển tức thời · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game), Phát triển server (Đội phát triển game)

Định tuyến đi đường vòng Suboptimal routing

Do hợp đồng kết nối giữa các nhà mạng, dữ liệu tới cả server ở gần cũng phải đi vòng qua nơi xa.

Vì sao: Nhà mạng của bạn và nhà mạng phía server không kết nối trực tiếp với nhau → Dẫn đến: Đi qua nước khác hoặc thành phố khác nên quãng đường và số thiết bị tăng lên → Trên màn hình: Chỉ người chơi của một nhà mạng nhất định có ping cao bất thường

Triệu chứng: Trễ thao tác · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Bên ngoài (Bên ngoài)

Nghẽn peering vào giờ cao điểm Peak-hour congestion at peering

Khoảng 9–11 giờ tối, lưu lượng video tăng vọt nên đoạn kết nối giữa các nhà mạng (peering) dễ bị nghẽn.

Vì sao: Buổi tối lưu lượng streaming và tải xuống dồn đến → Dẫn đến: Hàng đợi dồn lên và mất gói ở đoạn peering → Trên màn hình: Chỉ vào buổi tối, người chơi của một nhà mạng nhất định bị giật khựng hoặc dịch chuyển tức thời

Triệu chứng: Giật khựng, Dịch chuyển tức thời, Kéo ngược · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Bên ngoài (Bên ngoài)

Sự cố cáp quang biển, đường truyền quốc tế Submarine cable fault

Khi cáp quang biển bị đứt, dữ liệu phải đi vòng theo tuyến xa trong nhiều tuần (có khi nhiều tháng) cho đến khi sửa xong, và các đường truyền còn lại bị nghẽn.

Vì sao: Đứt cáp hoặc hỏng thiết bị → Dẫn đến: Lưu lượng dồn sang tuyến đường vòng xa và các đường truyền còn lại → Trên màn hình: Người chơi kết nối từ nước ngoài bị ping tăng vọt và mất gói kéo dài từ vài ngày đến vài tuần

Triệu chứng: Trễ thao tác, Dịch chuyển tức thời · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Hạ tầng mạng (Đội hạ tầng)

Thay đổi tuyến BGP và hội tụ Route change / BGP convergence

Khi thông tin định tuyến trên Internet thay đổi, gói tin bị mất trong vài giây đến vài chục giây (hiếm khi vài phút) cho đến khi định tuyến hội tụ trở lại.

Vì sao: Thông tin định tuyến ở đoạn mạng của một nhà mạng nào đó thay đổi → Dẫn đến: Trong vài giây đến vài chục giây, gói tin biến mất hoặc chuyển sang tuyến mới → Trên màn hình: Đột nhiên đứng hình vài giây, sau đó chỉ số ping đổi hẳn (ví dụ 40 → 70 ms)

Triệu chứng: Đứng hình, Dịch chuyển tức thời · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game), Bên ngoài (Bên ngoài)

Một đường ECMP bị lỗi ECMP / link bundle member fault

Nhà mạng và trung tâm dữ liệu thường có nhiều đường cùng đi tới một đích, và mỗi kết nối được gán cố định vào một đường. Nếu chỉ một đường bị hỏng, chỉ những người được gán vào đường đó liên tục bị lag.

Vì sao: Trong một đoạn gộp nhiều đường truyền, một đường truyền hoặc một thiết bị bị lỗi hay bị nghẽn → Dẫn đến: Đường đi được chọn theo tổ hợp địa chỉ và cổng (hash), nên chỉ những kết nối được gán vào đường đó bị mất gói và trễ → Trên màn hình: Cùng khu vực, cùng nhà mạng nhưng chỉ một số người liên tục bị dịch chuyển tức thời. Đôi khi kết nối lại là hết

Triệu chứng: Dịch chuyển tức thời, Kéo ngược, Giật khựng · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game), Bên ngoài (Bên ngoài)

Nhà mạng giới hạn tốc độ và quản lý lưu lượng Traffic shaping, data caps

Khi dùng vượt dung lượng data, hoặc với gói cước có quản lý một số loại lưu lượng, gói tin bị làm chậm hoặc bị bỏ.

Vì sao: Bị giới hạn tốc độ sau khi dùng hết data của gói cước, hoặc một số loại lưu lượng bị hạn chế → Dẫn đến: Gói tin phải chờ hoặc bị bỏ → Trên màn hình: Lag sau khi dùng đến một mức nhất định, nhất là trên di động

Triệu chứng: Trễ thao tác, Dịch chuyển tức thời · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển server (Đội phát triển game), Hạ tầng mạng (Đội hạ tầng)

Hạn chế UDP và kiểm tra gói tin ở cấp quốc gia hoặc nhà mạng UDP blocking, throttling and inspection by networks

Một số mạng chặn một số địa chỉ và cổng UDP nhất định hoặc giới hạn tốc độ UDP, còn thiết bị kiểm tra gói tin thì lọc bỏ các giao thức mà nó không nhận ra. Game giao tiếp bằng UDP sẽ không kết nối được hoặc hay bị mất kết nối trên các mạng đó.

Vì sao: Kết nối từ mạng của một số nhà mạng có giới hạn tốc độ UDP, hoặc từ mạng có thiết bị kiểm tra lưu lượng (kiểm duyệt) ở cấp quốc gia hoặc nhà mạng → Dẫn đến: Chặn một số địa chỉ và cổng UDP nhất định, giới hạn tốc độ UDP vào giờ đông, lọc bỏ các cổng và giao thức không có trong danh sách cho phép, hoặc chỉ cho vài gói đầu tiên đi qua rồi chặn → Trên màn hình: Chỉ người chơi ở một số quốc gia hoặc nhà mạng nhất định gặp tình trạng không vào được·kẹt loading, vào được rồi lại sớm mất kết nối, hoặc dịch chuyển tức thời do mất gói vào giờ đông

Triệu chứng: Không vào được·kẹt loading, Mất kết nối, Dịch chuyển tức thời · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game), Phát triển server (Đội phát triển game), Hạ tầng mạng (Đội hạ tầng)

Chất lượng đường truyền kém Faulty last-mile line / modem

Đầu nối tiếp xúc kém, dây cũ hoặc modem trục trặc gây mất gói đều đặn và làm đường truyền bị ngắt theo chu kỳ.

Vì sao: Cáp hỏng, tiếp xúc kém, modem hoặc thiết bị đầu cuối quang (ONT) trục trặc → Dẫn đến: Gói tin bị bỏ do lỗi bit; thỉnh thoảng đường truyền bị ngắt vài giây đến khoảng 1 phút để kết nối lại → Trên màn hình: Mất gói ít nhưng đều đặn, thỉnh thoảng đứng hình vài giây hoặc mất kết nối

Triệu chứng: Dịch chuyển tức thời, Đứng hình, Mất kết nối · Phụ trách chính Bên ngoài (Bên ngoài)

DNS lỗi hoặc chậm DNS failure / slowness

Nếu DNS, dịch vụ đổi tên server thành địa chỉ, bị chậm hoặc lỗi thì game không tìm được server đăng nhập hay server cập nhật.

Vì sao: DNS của nhà mạng gặp sự cố hoặc cấu hình sai → Dẫn đến: Không tìm được địa chỉ của server đăng nhập, server cập nhật → Trên màn hình: Bấm nút kết nối rồi chờ rất lâu hoặc không vào được. Người đã vào game vẫn bình thường

Triệu chứng: Không vào được·kẹt loading · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển client (Đội phát triển game)

Đường truyền dùng chung bị DDoS làm bão hòa DDoS saturating shared links

Các cuộc tấn công quy mô lớn nhắm vào công ty game, hoặc vào nơi khác trong cùng mạng, làm đầy đường truyền dùng chung.

Vì sao: Lưu lượng tấn công khổng lồ xuất hiện → Dẫn đến: Cả lưu lượng hợp lệ dùng chung đường truyền cũng bị dồn ứ và bị bỏ → Trên màn hình: Nhiều người cùng lúc bị dịch chuyển tức thời, mất kết nối hoặc không vào được

Triệu chứng: Dịch chuyển tức thời, Mất kết nối, Không vào được·kẹt loading · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Bên ngoài (Bên ngoài)

IP dùng chung của nhà mạng (CGNAT) Carrier-grade NAT

Mạng di động và một số nhà mạng cho nhiều thuê bao dùng chung một IP, và xóa ánh xạ (mapping) của kết nối nhàn rỗi sau một thời gian ngắn.

Vì sao: Thiết bị của nhà mạng quản lý bảng phiên của rất nhiều thuê bao → Dẫn đến: Giới hạn bảng phiên, idle timeout ngắn → Trên màn hình: Để yên một lúc thì mất kết nối; những người dùng chung IP bị chặn cùng lúc do phát hiện nhầm

Triệu chứng: Mất kết nối, Không vào được·kẹt loading · Phụ trách chính Phát triển client (Đội phát triển game) · Phối hợp Phát triển server (Đội phát triển game), Hạ tầng mạng (Đội hạ tầng)

Đi qua VPN hoặc phần mềm tăng tốc game VPN / game accelerator detour

Khi bật VPN hoặc phần mềm tăng tốc game, gói tin sẽ đi qua server trung chuyển của công ty đó. Nếu server trung chuyển ở xa hoặc đông, kết nối lại chậm hơn cả khi không bật.

Vì sao: VPN hoặc phần mềm tăng tốc chuyển toàn bộ gói tin của game qua server trung chuyển → Dẫn đến: Cộng thêm khoảng cách tới server trung chuyển và tình trạng nghẽn ở đó; header của tunnel còn làm MTU (kích thước gói tối đa gửi được trong một lần) nhỏ đi → Trên màn hình: Ping tăng và mất gói; bị chặn cùng với những người dùng chung địa chỉ trung chuyển nên không vào được

Triệu chứng: Trễ thao tác, Dịch chuyển tức thời, Không vào được·kẹt loading · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Hạ tầng mạng (Đội hạ tầng), Phát triển server (Đội phát triển game)

Thiết bị mạng trung tâm dữ liệu

Ngay trước khi tới server, gói tin lần lượt đi qua router, thiết bị chống DDoS, tường lửa, bộ cân bằng tải và switch. Bình thường chặng này mất chưa tới 1 ms, nhưng chỉ cần một thiết bị đầy dung lượng hoặc gặp sự cố là hàng nghìn người trên cả server cùng bị ảnh hưởng.

Mỗi thiết bị có vai trò riêng. Router chọn tuyến đường, thiết bị chống DDoS lọc bỏ lưu lượng tấn công, tường lửa chỉ cho các kết nối được phép đi qua và theo dõi mọi kết nối trong bảng phiên. Bộ cân bằng tải chia các kết nối đi vào cho nhiều server, còn switch nối các server với nhau.

Điểm yếu chung của các thiết bị này là kích thước bảng và kích thước bộ đệm. Bảng phiên của tường lửa đầy thì không nhận thêm kết nối mới; bộ cân bằng tải xóa các kết nối nhàn rỗi sau một khoảng thời gian; bộ đệm nhỏ của switch tràn trong chưa đầy 1 ms khi nhiều server cùng lúc gửi gói tin cho hàng nghìn người (world boss xuất hiện). Và khi một thiết bị hỏng rồi chuyển sang thiết bị dự phòng (failover), mọi người đều đứng hình trong vài giây đó.

So sánh

Lối vào trung tâm dữ liệu giống như quầy soi chiếu an ninh và cửa lên máy bay ở sân bay. Quầy an ninh (tường lửa) chỉ cho người có tên trong danh sách đi qua, danh sách kín chỗ thì không nhận thêm ai. Nhân viên cửa lên máy bay (bộ cân bằng tải) coi hành khách ngồi im quá lâu là “đã đi rồi” và gạch tên khỏi danh sách.

Các nguyên nhân gây lag ở tầng này

Bảng phiên của tường lửa bị đầy Firewall session table exhaustion

Tường lửa ghi mọi kết nối đã cho đi qua vào bảng phiên để theo dõi. Khi bảng đầy, tường lửa không nhận thêm được kết nối mới.

Vì sao: Số phiên chạm giới hạn do kết nối dồn dập hoặc bị tấn công → Dẫn đến: Không còn mục trống để ghi kết nối mới nên kết nối bị từ chối → Trên màn hình: Người đang cố vào game thì không vào được·kẹt loading, một số kết nối hiện có cũng bị mất kết nối

Triệu chứng: Không vào được·kẹt loading, Mất kết nối · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game), Phát triển client (Đội phát triển game)

Đi qua hệ thống chống DDoS, chặn nhầm DDoS scrubbing latency, false positives

Để chặn tấn công, lưu lượng được chuyển qua trung tâm lọc DDoS nên tuyến đường dài ra, và đôi khi người chơi bình thường bị nhầm là kẻ tấn công và bị chặn.

Vì sao: Sau khi phát hiện tấn công (hoặc thường trực), lưu lượng đi vào được chuyển vòng qua trung tâm lọc DDoS → Dẫn đến: Tuyến đường dài ra, một số gói hợp lệ bị xác định là tấn công → Trên màn hình: Ping chung tăng, chỉ một số khu vực hoặc nhà mạng không vào được

Triệu chứng: Trễ thao tác, Không vào được·kẹt loading, Dịch chuyển tức thời · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Idle timeout của bộ cân bằng tải Load balancer idle timeout

Bộ cân bằng tải xóa kết nối nhàn rỗi sau một khoảng thời gian nhất định. Game vẫn coi là kết nối còn đó cho đến lúc bị mất kết nối.

Vì sao: Người chơi một lúc không gửi gói nào (đang ở cửa sổ chat, rời máy) → Dẫn đến: Bộ cân bằng tải dọn kết nối nhàn rỗi (giá trị mặc định thường gặp là 60–350 giây) → Trên màn hình: Mất kết nối ngay khi di chuyển lại

Triệu chứng: Mất kết nối · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Phát triển client (Đội phát triển game), Phát triển server (Đội phát triển game)

Hết hạn theo dõi kết nối của security group trên cloud Cloud security group connection tracking timeout

Tường lửa gắn với server cloud (security group) cũng theo dõi kết nối, và mục theo dõi của kết nối nhàn rỗi sẽ hết hạn sau một khoảng thời gian định sẵn. Ngay cả với server nhận kết nối trực tiếp không qua bộ cân bằng tải, người chơi để yên một lúc cũng có thể bị mất kết nối.

Vì sao: Security group được cấu hình theo cách có theo dõi kết nối game (chỉ cho phép một số địa chỉ, hạn chế quy tắc chiều ra, đi qua NLB…) → Dẫn đến: Mục theo dõi của kết nối đã nhàn rỗi một lúc bị hết hạn, và các gói đến sau đó bị security group âm thầm bỏ → Trên màn hình: Rời máy một lúc rồi quay lại di chuyển thì không có phản hồi, sau đó mất kết nối. Chương trình server rất lâu sau mới biết

Triệu chứng: Mất kết nối · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển client (Đội phát triển game), Phát triển server (Đội phát triển game)

Giới hạn kết nối và cổng của NAT gateway trên cloud Cloud NAT gateway connection / port limits

Các kết nối từ server trong subnet riêng đi ra ngoài (xác thực nền tảng, thanh toán, API bên ngoài) được NAT gateway đổi địa chỉ và cổng rồi gửi đi. Nếu số kết nối đồng thời tới cùng một đích vượt giới hạn cổng của gateway, kết nối mới sẽ thất bại.

Vì sao: Các server mở nhiều kết nối ngắn hoặc giữ kết nối lâu tới cùng một địa chỉ bên ngoài như xác thực nền tảng, thanh toán → Dẫn đến: NAT gateway không cấp thêm được cổng nguồn cho đích đó nên kết nối mới thất bại → Trên màn hình: Trong game vẫn bình thường, nhưng riêng các tính năng gọi ra ngoài như đăng nhập, thanh toán, phát thưởng thất bại hoặc chậm (không vào được·kẹt loading, nuốt thao tác·rollback)

Triệu chứng: Không vào được·kẹt loading, Nuốt thao tác·rollback · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Bộ cân bằng tải phân bổ lệch, health check đánh giá sai LB imbalance, bad health checks

Kết nối dồn vào một server, hoặc người chơi cứ bị gửi tới server đã chết.

Vì sao: Quy tắc phân bổ không phù hợp, hoặc health check không phản ánh trạng thái thực → Dẫn đến: Chỉ một server bị quá tải, hoặc người chơi cố kết nối tới server đã chết → Trên màn hình: Chỉ một số kênh hoặc một số người bị quay chậm, không vào được·kẹt loading

Triệu chứng: Quay chậm, Không vào được·kẹt loading · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Microburst ở switch Switch microburst drops

Khi nhiều server cùng lúc gửi dồn gói tin tới hàng nghìn người, bộ đệm nhỏ của cổng switch nơi lưu lượng đó hội tụ sẽ tràn trong chưa tới 1 ms.

Vì sao: World boss xuất hiện, skill diện rộng, hoặc tick của nhiều server trùng đúng một thời điểm nên gửi dồn một lượt → Dẫn đến: Bộ đệm (vài trăm KB đến vài MB mỗi cổng) ở nơi nhiều cổng dồn vào một cổng, hoặc nơi chuyển từ cổng nhanh sang cổng chậm, bị đầy trong tích tắc → Trên màn hình: Một phần gói tin bị bỏ, nhiều người cùng lúc bị dịch chuyển tức thời hoặc nuốt skill

Triệu chứng: Dịch chuyển tức thời, Nuốt thao tác·rollback · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng mạng (Đội hạ tầng), Hạ tầng server (Đội hạ tầng)

Đường truyền trung tâm dữ liệu bị bão hòa Uplink saturation

Nếu việc phân phối bản cập nhật, gửi log, sao lưu dùng chung đường truyền với game thì đường truyền bị đầy.

Vì sao: Truyền dữ liệu dung lượng lớn chiếm giữ cùng đường truyền → Dẫn đến: Hàng đợi trên đường truyền và mất gói tăng → Trên màn hình: Ping toàn server tăng và dịch chuyển tức thời

Triệu chứng: Trễ thao tác, Dịch chuyển tức thời · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Hạ tầng server (Đội hạ tầng)

Failover thiết bị mạng Network device failover

Khi một router hay tường lửa hỏng và chuyển sang thiết bị dự phòng (failover), mọi người đều bị đứng hình trong vài giây chuyển đổi đó.

Vì sao: Chuyển sang thiết bị dự phòng do thiết bị hỏng hoặc bảo trì → Dẫn đến: Chuyển đổi mất vài giây, nếu thông tin phiên không được đồng bộ thì kết nối bị reset → Trên màn hình: Mọi người chơi của server cùng lúc đứng hình, mất kết nối hàng loạt

Triệu chứng: Đứng hình, Mất kết nối · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game), Phát triển client (Đội phát triển game)

Cáp hỏng và lỗi cổng Bad cable / optics (CRC errors)

Nếu module quang hoặc cáp bị lỗi, gói tin đi qua đường đó bị hỏng theo một tỷ lệ nhất định.

Vì sao: Lỗi bit do module quang hoặc cáp bị lỗi → Dẫn đến: Gói bị hỏng bị thiết bị âm thầm bỏ → Trên màn hình: Chỉ một số server hoặc người chơi đi qua đường đó bị mất gói đều đặn, gây dịch chuyển tức thời hoặc kéo ngược

Triệu chứng: Dịch chuyển tức thời, Kéo ngược · Phụ trách chính Hạ tầng mạng (Đội hạ tầng)

MTU không khớp (chỉ mất gói lớn) MTU black hole

Khi MTU (kích thước gửi được trong một lần) của một chặng ở giữa nhỏ đi mà thông báo vượt kích thước lại bị chặn, chỉ các gói lớn liên tục bị mất.

Vì sao: MTU nhỏ đi ở chặng tunnel hoặc VPN → Dẫn đến: Thông báo vượt kích thước (ICMP) bị tường lửa chặn nên bên gửi không biết → Trên màn hình: Chỉ khi mở màn hình lớn như túi đồ, danh sách nhân vật thì đứng hình rồi mất kết nối

Triệu chứng: Đứng hình, Mất kết nối, Không vào được·kẹt loading · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Hạ tầng server (Đội hạ tầng), Phát triển server (Đội phát triển game)

Card mạng server (NIC)

Card mạng gắn trên server nhận hàng trăm nghìn đến hàng triệu gói tin mỗi giây rồi chuyển cho CPU. Nếu ở đây xử lý không kịp, gói tin sẽ mất trước cả khi chương trình server biết là nó đã đến.

NIC lần lượt đặt các gói tin vừa đến vào ring buffer (bộ đệm nhận có số slot cố định, dùng xoay vòng) rồi báo cho CPU “có gói tin tới” (ngắt). CPU lấy gói tin ra khỏi ring buffer và chuyển cho OS. Nếu gói tin vào nhanh hơn tốc độ CPU lấy ra, mọi slot sẽ đầy và các gói đến sau bị bỏ. Chỉ có con số trong thống kê của card mạng (ethtool -S) lặng lẽ tăng lên, còn log của server game không có lỗi nào, nên đây là loại lag khó tìm.

NIC ngày nay có nhiều hàng đợi nhận (ring buffer) và có thể chia việc thông báo cho nhiều core CPU (RSS), nhưng nếu chưa cấu hình hoặc lưu lượng dồn vào một hàng đợi thì chỉ một core lên 100% và trở thành điểm nghẽn. Với server trên cloud, phía trước NIC còn có riêng giới hạn số gói mỗi giây, băng thông và số kết nối; phần vượt quá bị bỏ trước khi tới server. Hiện tượng này không lộ ra trên các chỉ số quen thuộc như CPU hay ring buffer; trên AWS, nó chỉ để lại dấu vết trong thống kê của driver ENA (pps_allowance_exceeded, v.v. trong ethtool -S).

So sánh

NIC là hộp thư của tòa chung cư, ring buffer là số ngăn của hộp thư, còn ngắt là tiếng chuông của người đưa thư. Thư đổ về ào ạt mà chỉ có một người lấy thì các ngăn tràn và thư rơi xuống đất. RSS là bố trí nhiều người cùng lấy thư.

Các nguyên nhân gây lag ở tầng này

Ngắt NIC dồn vào một core Single-queue NIC / no RSS

Nếu NIC chỉ gửi ngắt báo gói tin đến cho một core CPU, core đó sẽ thành điểm nghẽn.

Vì sao: Chỉ có một hàng đợi nhận, hoặc RSS (phân tán ra nhiều core) đang tắt → Dẫn đến: Một core lên 100% nên không lấy gói tin ra kịp → Trên màn hình: Khi đông người, toàn server bị mất gói và trễ (dịch chuyển tức thời, trễ thao tác)

Triệu chứng: Dịch chuyển tức thời, Kéo ngược, Trễ thao tác · Phụ trách chính Hạ tầng server (Đội hạ tầng)

Ring buffer không đủ RX ring buffer overflow

Nếu ring buffer, nơi NIC tạm giữ gói tin, quá nhỏ thì khi gói dồn đến trong tích tắc, bộ đệm sẽ tràn và gói bị bỏ.

Vì sao: Ring buffer để ở giá trị mặc định nhỏ (256–2.048 slot tùy driver) → Dẫn đến: Khi có burst, bộ đệm tràn trước khi CPU kịp lấy gói ra → Trên màn hình: Chỉ mất gói vào lúc burst (dịch chuyển tức thời, nuốt skill). Log của server game không để lại dấu vết

Triệu chứng: Dịch chuyển tức thời, Nuốt thao tác·rollback · Phụ trách chính Hạ tầng server (Đội hạ tầng)

Gộp ngắt quá mức Interrupt coalescing

Để giảm tải cho CPU, NIC gom gói tin lại rồi báo một lần, nên gói bị trễ đúng bằng thời gian gom.

Vì sao: NIC gom đủ một khoảng thời gian hoặc số lượng gói nhất định rồi mới báo → Dẫn đến: Gói tin phải chờ trong lúc gom → Trên màn hình: Độ trễ tăng nhẹ. Thường nhỏ, nhưng nếu quá mức thì lên tới mức ms

Triệu chứng: Trễ thao tác · Phụ trách chính Hạ tầng server (Đội hạ tầng)

Vượt giới hạn PPS trên cloud Cloud PPS / bandwidth allowance

Server cloud có giới hạn số gói mỗi giây và băng thông theo từng loại instance, vượt quá thì gói bị bỏ âm thầm.

Vì sao: Số người chơi đồng thời tăng làm số gói mỗi giây vượt giới hạn của instance → Dẫn đến: Mạng của cloud bỏ phần vượt → Trên màn hình: Mất gói không rõ nguyên nhân gây dịch chuyển tức thời hoặc nuốt skill. CPU server vẫn dư

Triệu chứng: Dịch chuyển tức thời, Nuốt thao tác·rollback · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game), Bên ngoài (Bên ngoài)

Băng thông NIC bị bão hòa NIC bandwidth saturation

Khi dùng tới giới hạn của card 1 Gbps hay 10 Gbps, hàng đợi gửi dài ra và cuối cùng gói bị bỏ.

Vì sao: Broadcast tăng làm lượng dữ liệu gửi chạm giới hạn của card → Dẫn đến: Hàng đợi gửi dài ra, tràn thì gói bị bỏ → Trên màn hình: Toàn server bị trễ và mất gói (trễ thao tác, dịch chuyển tức thời)

Triệu chứng: Trễ thao tác, Dịch chuyển tức thời · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

Overhead ảo hóa và noisy neighbor Noisy neighbors in virtualization

Nếu máy ảo khác trên cùng server vật lý dùng nhiều mạng và CPU, việc xử lý trên server của bạn bị chậm lại một cách thất thường.

Vì sao: Máy ảo khác trên cùng server vật lý dùng nhiều tài nguyên → Dẫn đến: Việc xử lý gói tin của máy ảo của bạn bị trễ thất thường → Trên màn hình: Không có nguyên nhân rõ ràng mà thỉnh thoảng xuất hiện jitter (độ dao động của khoảng cách giữa các lần gói tin đến), gây giật khựng

Triệu chứng: Giật khựng · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Bên ngoài (Bên ngoài)

Bảo trì host cloud và live migration Cloud host maintenance / live migration

Khi nhà cung cấp cloud bảo trì server vật lý (host), họ chuyển máy ảo sang host khác (live migration) hoặc tạm dừng máy ảo một lúc. Trong lúc đó cả server bị đứng, nếu thời gian dừng dài thì kết nối bị ngắt.

Vì sao: Nhà cung cấp chuyển máy ảo sang host khác hoặc tạm dừng một lúc do bảo trì host hay dự đoán hỏng hóc → Dẫn đến: Trong lúc chuyển, CPU, bộ nhớ, mạng chậm đi, và ở bước cuối máy ảo dừng hẳn trong chốc lát (từ dưới 1 giây đến khoảng 30 giây, tùy nhà cung cấp và cách làm) → Trên màn hình: Mọi người trên server cùng đứng hình rồi tua nhanh hoặc dịch chuyển tức thời; nếu thời gian dừng dài hơn timeout thì mất kết nối hàng loạt

Triệu chứng: Đứng hình, Tua nhanh, Dịch chuyển tức thời, Mất kết nối · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game), Bên ngoài (Bên ngoài)

Lỗi driver hoặc firmware NIC NIC hang / reset

Do lỗi driver hoặc tính năng hoạt động sai, card mạng bị treo và khởi động lại, trong lúc đó mọi việc gửi nhận đều bị ngắt.

Vì sao: Lỗi driver, tính năng offload hoạt động sai → Dẫn đến: NIC treo rồi khởi động lại (vài giây) → Trên màn hình: Mọi người trên server đó cùng đứng hình rồi dịch chuyển tức thời hoặc mất kết nối

Triệu chứng: Đứng hình, Mất kết nối · Phụ trách chính Hạ tầng server (Đội hạ tầng)

Độ trễ chờ gộp gói GRO/LRO GRO/LRO batching

Đây là tính năng gộp nhiều gói thành một để giảm tải cho CPU. Tùy cấu hình, gói game nhỏ đôi khi phải chờ một chút gói tiếp theo để gộp cùng.

Vì sao: NIC và kernel gộp các gói đã đến lại để xử lý → Dẫn đến: Nếu bật gộp bằng phần cứng (LRO) hoặc cấu hình thời gian chờ gộp, gói phải chờ một chút để đợi gói tiếp theo → Trên màn hình: Độ trễ tăng nhẹ (thường không quá vài chục µs)

Triệu chứng: Trễ thao tác · Phụ trách chính Hạ tầng server (Đội hạ tầng)

OS server (kernel)

Kernel Linux hay Windows của server nhận kết nối, quản lý bộ đệm socket và chia CPU, bộ nhớ cho chương trình server game. Phần lớn giá trị mặc định là giá trị thận trọng, hợp với nhiều mục đích chung, nên nhiều khi không hợp với server game có hàng chục nghìn người kết nối trong thời gian dài.

Khi có kết nối mới, kernel đặt yêu cầu kết nối vào hàng đợi kết nối (backlog) để server game lấy ra từng cái một. Hàng đợi đầy thì Linux lặng lẽ bỏ yêu cầu mới, còn Windows gửi lại phản hồi từ chối. Trên Linux, mỗi kết nối cần một file descriptor (fd), tức con số gắn với mỗi file hay kết nối đang mở, và số fd một tiến trình được giữ cũng có giới hạn. Khi hàng chục nghìn người cùng bấm nút kết nối ngay sau bảo trì, hàng đợi kết nối và fd là thứ cạn trước tiên.

Kernel còn đẩy bộ nhớ ra ổ đĩa khi thiếu (swap, nếu được bật), và khi thực sự cạn thì Linux chọn tiến trình dùng nhiều bộ nhớ nhất để buộc tắt (OOM killer). Server game thường là tiến trình dùng nhiều bộ nhớ nhất trên server đó nên là đối tượng bị tắt đầu tiên. Nếu container được đặt giới hạn bộ nhớ, dù cả server vẫn còn dư, điều tương tự cũng xảy ra ngay khi chạm giới hạn. Những việc tưởng không liên quan đến game như đồng bộ thời gian (NTP), tác vụ định kỳ, giới hạn CPU của container, CPU steal của máy ảo (thời gian chờ trong lúc máy ảo khác dùng CPU vật lý) cũng làm server dừng từng chốc hoặc làm timer bị lệch.

So sánh

OS server giống như cổng soát vé và văn phòng quản lý của công viên giải trí. Đến giờ mở cửa (kết thúc bảo trì) mà mọi người ùa tới thì hàng trước cổng (backlog) tràn ra, và khi hết vòng đeo tay để phát (file descriptor) thì không ai vào thêm được.

Các nguyên nhân gây lag ở tầng này

Tràn hàng đợi kết nối (backlog) Listen backlog / SYN queue overflow

Ngay sau bảo trì, khi hàng chục nghìn người chơi kết nối cùng lúc, hàng đợi kết nối (backlog) của kernel bị tràn và các yêu cầu kết nối bị bỏ.

Vì sao: Vừa hết bảo trì, kết nối đổ về nhanh hơn tốc độ server game xử lý bằng accept → Dẫn đến: Hàng đợi kết nối của kernel (backlog, lấy giá trị nhỏ hơn giữa giá trị code server truyền cho listen và giới hạn của kernel) bị đầy → Trên màn hình: Yêu cầu kết nối bị bỏ, client thử lại hết lần này đến lần khác, dẫn đến không vào được·kẹt loading

Triệu chứng: Không vào được·kẹt loading · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng), Phát triển client (Đội phát triển game)

Giới hạn file descriptor File descriptor limit (ulimit)

Mỗi kết nối cần một file descriptor (fd, con số OS gán cho mỗi file hoặc socket đang mở), nhưng số fd mà một tiến trình được mở có giới hạn.

Vì sao: Số người chơi đồng thời chạm giới hạn file descriptor của tiến trình → Dẫn đến: Server không nhận được kết nối mới (Too many open files). Việc mở file log và kết nối DB cũng thất bại theo → Trên màn hình: Từ đúng một mức số người nhất định trở đi, mọi người mới vào đều gặp không vào được·kẹt loading

Triệu chứng: Không vào được·kẹt loading · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Bộ đệm socket của kernel quá nhỏ Small socket buffers

Khi bộ đệm gửi và nhận nhỏ, lúc lưu lượng dồn thành burst, gói UDP nhận về sẽ bị bỏ, còn việc gửi qua TCP bị chặn vì bộ đệm hết chỗ.

Vì sao: SO_SNDBUF và SO_RCVBUF để mặc định hoặc quá nhỏ → Dẫn đến: Khi có burst hoặc khi thread nhận dừng một chút, bộ đệm nhận UDP bị tràn và gói bị bỏ; TCP phải chờ vì bộ đệm gửi hết chỗ → Trên màn hình: Dịch chuyển tức thời (mất gói UDP) hoặc tua nhanh (TCP phải chờ)

Triệu chứng: Dịch chuyển tức thời, Tua nhanh · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Quá nhiều thread và context switch Thread oversubscription, context switching

Chạy số thread nhiều hơn số core rất nhiều thì OS tốn CPU chỉ để cho chúng chạy luân phiên.

Vì sao: Có hàng trăm đến hàng nghìn thread, chẳng hạn mỗi kết nối một thread → Dẫn đến: Chi phí context switch (đổi thread đang chạy) tăng, cache miss cũng tăng → Trên màn hình: CPU bận nhưng thông lượng thấp, tick không đều, gây giật khựng và quay chậm

Triệu chứng: Giật khựng, Quay chậm · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

CPU steal (máy ảo) CPU steal time

Trong lúc server vật lý (hypervisor) tạm chuyển thời gian CPU của một máy ảo cho máy ảo khác (CPU steal), server game bị dừng.

Vì sao: Máy ảo khác trên cùng host dùng nhiều CPU → Dẫn đến: Máy ảo chạy server game mất lượt dùng CPU, mỗi lần vài ms đến vài chục ms → Trên màn hình: Thời gian tick vọt lên không rõ lý do, gây giật khựng và đứng hình

Triệu chứng: Giật khựng, Đứng hình · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Bên ngoài (Bên ngoài)

CPU throttling trong container (CFS quota) Container CPU throttling (CFS quota)

Khi container bị đặt giới hạn CPU, ngay lúc dùng hết quota trong một chu kỳ cố định (thường là 100 ms), container bị buộc dừng trong phần thời gian còn lại của chu kỳ đó (throttling).

Vì sao: Container server game bị đặt giới hạn CPU (limit), ví dụ trên Kubernetes → Dẫn đến: Lúc tính toán tick dồn lại, container dùng hết quota và dừng vài chục ms cho đến chu kỳ sau → Trên màn hình: CPU trung bình thấp nhưng tick vọt lên theo chu kỳ, gây giật khựng và quay chậm

Triệu chứng: Giật khựng, Quay chậm · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Độ trễ vọt lên do quản lý nguồn điện của server (C-state, điều chỉnh xung nhịp) CPU power management latency (C-states, frequency scaling)

Core CPU đang rảnh sẽ vào trạng thái tiết kiệm điện sâu (C-state) và hạ xung nhịp để tiết kiệm điện. Khi có gói tin hoặc timer đến, core cần thời gian để thức dậy và nâng xung nhịp, nên việc xử lý gói nhỏ bị cộng thêm độ trễ.

Vì sao: Chính sách điều chỉnh xung nhịp (governor) của OS hoặc cấu hình nguồn điện trong BIOS cho phép C-state sâu và xung nhịp thấp → Dẫn đến: Mỗi lần thức dậy từ trạng thái tiết kiệm điện sâu, core đang rảnh chậm tối đa vài trăm µs; nếu xung nhịp bị ghim ở mức thấp thì bản thân việc tính tick cũng chậm đi → Trên màn hình: Thường khó cảm nhận, nhưng khi có nhiều lời gọi giữa các server, độ trễ cộng dồn thành trễ thao tác, và lúc vắng người phản hồi lại chậm hơn. Nếu xung nhịp bị ghim thấp, lúc đông người tick bị dồn lại, gây quay chậm

Triệu chứng: Trễ thao tác, Quay chậm · Phụ trách chính Hạ tầng server (Đội hạ tầng)

OOM killer Out-of-memory killer

Khi bộ nhớ cạn, Linux chọn tiến trình dùng nhiều bộ nhớ nhất và buộc kết thúc (kill) nó. Thường đó là server game.

Vì sao: Bộ nhớ cạn do rò rỉ hoặc tăng đột biến, hoặc container chạm giới hạn bộ nhớ → Dẫn đến: Kernel buộc kết thúc tiến trình server game → Trên màn hình: Mọi người trên server đó cùng mất kết nối, tiến độ gần nhất có thể bị rollback

Triệu chứng: Mất kết nối, Nuốt thao tác·rollback · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

Dừng do thu hồi bộ nhớ và compaction Memory compaction / reclaim stalls (THP)

Tiến trình bị dừng trong lúc OS dồn bộ nhớ (compaction) để tạo huge page, hoặc thu hồi bộ nhớ để có thêm chỗ trống.

Vì sao: Bộ nhớ trống giảm, hoặc tính năng huge page (THP) kích hoạt compaction bộ nhớ → Dẫn đến: Thread xin bộ nhớ phải chờ đến khi thu hồi hoặc compaction xong → Trên màn hình: Server dừng thất thường (vài ms đến vài trăm ms)

Triệu chứng: Đứng hình, Giật khựng · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Đồng hồ hệ thống nhảy (NTP step) Wall-clock jump (NTP step)

Khi đồng hồ server bị chỉnh tới hoặc lùi vài giây trong một lần, các timer dựa vào đồng hồ hệ thống sẽ kích hoạt dồn một lượt hoặc dừng hẳn.

Vì sao: Dịch vụ đồng bộ thời gian chỉnh đồng hồ một lần với biên độ lớn → Dẫn đến: Timer kích hoạt dồn một lượt hoặc dừng, timeout bị xác định sai → Trên màn hình: Buff và hồi chiêu bất thường, mất kết nối đồng loạt, tua nhanh

Triệu chứng: Tua nhanh, Mất kết nối, Nuốt thao tác·rollback · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

Tác vụ theo lịch Cron jobs (log rotation, backup, scans)

Các tác vụ nén log, sao lưu và quét bảo mật chạy vào cùng một giờ mỗi ngày chiếm CPU và ổ đĩa.

Vì sao: Tác vụ của OS chạy vào giờ đã định → Dẫn đến: Tác vụ dùng chung CPU và ổ đĩa với server game → Trên màn hình: Giật khựng và quay chậm vào giờ cố định, ví dụ 4 giờ sáng mỗi ngày

Triệu chứng: Giật khựng, Quay chậm · Phụ trách chính Hạ tầng server (Đội hạ tầng)

Hiệu năng thay đổi sau khi cập nhật OS, kernel, driver hoặc firmware Performance regression after OS / kernel / driver / firmware update

Code game không đổi, nhưng server chậm đi kể từ khi cập nhật OS, kernel, driver hoặc firmware. Bản cập nhật có thể làm thay đổi giá trị mặc định, bộ lập lịch, các biện pháp giảm thiểu lỗ hổng CPU (mitigations) và cách driver hoạt động.

Vì sao: Bản vá bảo mật định kỳ hoặc image server mới làm thay đổi kernel, driver hoặc firmware → Dẫn đến: Giá trị mặc định hoặc bộ lập lịch thay đổi, hoặc biện pháp giảm thiểu lỗ hổng mới được bật, khiến cùng một việc tốn nhiều thời gian CPU hơn và thứ tự thread được cấp CPU thay đổi → Trên màn hình: Server đang chạy tốt bỗng luôn chậm hơn một chút kể từ ngày cập nhật, gây trễ thao tác; lúc đông người thì giật khựng và quay chậm

Triệu chứng: Trễ thao tác, Giật khựng, Quay chậm · Phụ trách chính Hạ tầng server (Đội hạ tầng)

Bảng conntrack của server bị đầy conntrack table full

Khi bảng theo dõi kết nối (conntrack), nơi tường lửa Linux ghi lại mọi kết nối, chạm giới hạn, gói tin mới sẽ bị bỏ.

Vì sao: Kết nối dồn dập và kết nối ngắn lặp lại liên tục làm số mục kết nối tăng → Dẫn đến: Bảng đầy, kết nối mới và một phần gói tin bị bỏ → Trên màn hình: Không vào được, dịch chuyển tức thời do mất gói không rõ lý do

Triệu chứng: Không vào được·kẹt loading, Dịch chuyển tức thời · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game), Phát triển client (Đội phát triển game)

Cạn cổng tạm (ephemeral port) ở kết nối giữa các server Ephemeral port exhaustion (TIME_WAIT)

Khi server game mở rồi đóng kết nối ngắn tới DB hoặc server khác quá thường xuyên, các kết nối đã đóng vẫn chiếm giữ cổng một thời gian, nên không mở được kết nối mới.

Vì sao: Mỗi yêu cầu lại mở rồi đóng một kết nối mới → Dẫn đến: Bên đóng trước chiếm giữ cổng khoảng 60 giây (Linux) ở trạng thái TIME_WAIT, nên hết cổng để dùng → Trên màn hình: Yêu cầu nội bộ thất bại, gây lỗi lưu dữ liệu và lỗi tính năng

Triệu chứng: Nuốt thao tác·rollback, Không vào được·kẹt loading · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

Socket và giao thức: TCP, UDP, tùy chọn socket

Đây là phần quyết định cách game gửi và nhận dữ liệu qua mạng. Cùng một đường truyền, nhưng tùy giao thức được dùng và cách bật tùy chọn socket, việc mất một gói tin có thể chỉ gây “khựng nhẹ”, cũng có thể thành “đứng 1 giây rồi tua nhanh”.

TCP bảo đảm dữ liệu được chuyển đầy đủ và đúng thứ tự đã gửi. Đổi lại, khi mất một gói, nó giữ lại và chờ, không chuyển cho game cả những gói đến sau cho đến khi nhận lại được gói bị mất. UDP không bảo đảm gì cả. Gói nào đến thì được chuyển ngay không phải chờ, nhưng gói bị mất thì game phải tự xử lý. Vì vậy, game có tính hành động cao thường tự cài đặt độ tin cậy ở mức vừa đủ trên nền UDP (UDP tin cậy), còn nhiều MMO dùng TCP vì dễ cài đặt và chấp nhận điểm yếu của nó.

Tùy chọn socket là các thiết lập chi tiết cho hành vi này: có gom gói nhỏ lại rồi mới gửi không (TCP_NODELAY), để bộ đệm gửi và nhận lớn bao nhiêu (SO_SNDBUF, SO_RCVBUF), khi nào nhận ra kết nối đã chết (SO_KEEPALIVE, TCP_USER_TIMEOUT), xử lý dữ liệu còn lại thế nào khi đóng (SO_LINGER). Giá trị mặc định phần lớn được tối ưu cho việc gửi dữ liệu lớn bằng ít gói một cách hiệu quả, nên thường bất lợi cho game vốn trao đổi gói nhỏ liên tục.

Điểm mấu chốt

TCP chỉ chuyển dữ liệu đã nhận cho game theo đúng thứ tự đã gửi. Nếu gói số 17 bị mất, dù các gói 18–30 đã đến, tất cả vẫn phải chờ đến khi gói 17 được gửi lại (HOL blocking). UDP thì gói nào đến là chuyển ngay, nên dù gói 17 không bao giờ tới, các gói còn lại vẫn được xử lý đúng lúc.

Vì sao truyền lại xảy ra (Wi-Fi, tắc nghẽn, MTU black hole, truyền lại không cần thiết, v.v.) và cách tìm nguyên nhân được trình bày theo từng nguyên nhân ở chương 06 Truyền lại TCP.

Các nguyên nhân gây lag ở tầng này

TCP HOL blocking Head-of-line blocking

Để giữ đúng thứ tự, TCP không giao cho game các gói đến sau cho tới khi nhận lại được gói bị mất đó.

Vì sao: Một gói tin bị mất → Dẫn đến: Các gói phía sau đã đến nhưng phải nằm chờ trong bộ đệm nhận → Trên màn hình: Game đứng hình rồi dữ liệu ùa ra cùng một lúc, gây tua nhanh

Triệu chứng: Đứng hình, Tua nhanh · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

TCP RTO và exponential backoff RTO and exponential backoff

Mỗi lần truyền lại tiếp tục thất bại, thời gian chờ lại tăng gấp đôi, nên đường truyền chỉ đứt chốc lát cũng thành một lần đứng dài.

Vì sao: Đường truyền bị đứt trong chốc lát, các lần truyền lại cũng liên tiếp thất bại → Dẫn đến: Thời gian chờ đến lần thử sau tăng gấp đôi mỗi lần, như 0,3 → 0,6 → 1,2 → 2,4 giây (với ping 100 ms) → Trên màn hình: Đường truyền chỉ đứt 1 giây nhưng game đứng hình hơn 2 giây. Đứt lâu hơn thì cuối cùng mất kết nối

Triệu chứng: Đứng hình, Mất kết nối · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Thuật toán Nagle + delayed ACK Nagle + delayed ACK (TCP_NODELAY off)

Thuật toán Nagle (gom gói nhỏ lại để gửi) và delayed ACK (gửi ACK muộn) tác động chồng lên nhau, nên mỗi lần tách một message ra ghi nhiều lần là bị trễ 40–200 ms.

Vì sao: Tách message nhỏ ra ghi nhiều lần mà không bật TCP_NODELAY → Dẫn đến: Bên gửi chờ ACK, còn bên nhận thì gửi ACK muộn → Trên màn hình: Ping đường truyền thấp nhưng mọi thao tác lúc nào cũng ì ạch như nhau, gây trễ thao tác

Triệu chứng: Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Gửi bị chặn (blocking send) do client chậm Blocking send on a full socket

Khi bộ đệm gửi của một người chơi có đường truyền chậm đã đầy mà server gửi theo kiểu blocking (lời gọi gửi không trả về cho tới khi bộ đệm có chỗ trống), thread của server phải chờ đúng một người đó.

Vì sao: Bộ đệm gửi của một client chậm bị đầy → Dẫn đến: Vì gửi kiểu blocking nên thread server phải chờ đến khi bộ đệm có chỗ trống → Trên màn hình: Mọi người chơi do thread đó phụ trách đều bị đứng hình hoặc quay chậm

Triệu chứng: Đứng hình, Quay chậm · Phụ trách chính Phát triển server (Đội phát triển game)

Chính sách xử lý client chậm (slow consumer) Slow-consumer policy

Với client mà dữ liệu cần gửi cứ dồn lên mãi, server bỏ bớt các bản cập nhật cũ hoặc ngắt kết nối.

Vì sao: Đường truyền của client không theo kịp lượng dữ liệu server gửi → Dẫn đến: Server bỏ các bản cập nhật cũ, hoặc ngắt kết nối khi vượt giới hạn → Trên màn hình: Chỉ người chơi đó bị dịch chuyển tức thời hoặc mất kết nối

Triệu chứng: Dịch chuyển tức thời, Mất kết nối · Phụ trách chính Phát triển server (Đội phát triển game)

Keepalive mặc định 2 giờ TCP keepalive defaults

Khi bên kia biến mất mà không gửi tín hiệu đóng kết nối, rất lâu sau TCP mới phát hiện. Keepalive (tính năng của TCP kiểm tra xem kết nối nhàn rỗi còn sống không) mặc định tắt, và dù có bật thì kết nối cũng phải nhàn rỗi 2 giờ mới bắt đầu kiểm tra.

Vì sao: Client biến mất mà không có tín hiệu đóng kết nối, do mất điện hoặc rớt đường truyền → Dẫn đến: Server coi kết nối vẫn còn sống (keepalive mặc định 7.200 giây; nếu đang gửi dở dữ liệu thì mất khoảng 15 phút mới bỏ truyền lại) → Trên màn hình: Nhân vật ma còn nằm lại, vào lại game thì bị lỗi “Tài khoản đang đăng nhập”

Triệu chứng: Không vào được·kẹt loading, Không hiển thị·đối tượng ma · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game), Hạ tầng server (Đội hạ tầng)

Phân mảnh IP của gói UDP IP fragmentation of large UDP

Gói UDP lớn hơn MTU (kích thước tối đa gửi được trong một lần) bị phân mảnh ở tầng IP, và chỉ cần mất một fragment là cả gói bị bỏ.

Vì sao: Snapshot ở nơi đông người vượt quá 1.500 byte → Dẫn đến: Gói bị chia thành nhiều fragment để gửi, mất một fragment là bỏ cả gói → Trên màn hình: Gói lớn có tỷ lệ mất cao gấp mấy lần. Chỉ bị dịch chuyển tức thời ở nơi đông người

Triệu chứng: Dịch chuyển tức thời · Phụ trách chính Phát triển server (Đội phát triển game)

Cấu hình truyền lại của UDP tin cậy Reliable-UDP tuning (KCP, ENet…)

Quy tắc truyền lại tự xây trên UDP mà quá thận trọng thì khôi phục chậm, còn quá mạnh tay thì càng làm nghẽn đường truyền.

Vì sao: Khoảng cách truyền lại, số lần thử và kích thước cửa sổ được cấu hình không hợp với đường truyền → Dẫn đến: Khôi phục chậm, hoặc gửi trùng lặp làm tắc nghẽn nặng thêm → Trên màn hình: Nuốt skill, tua nhanh, lag nặng hơn khi mạng tắc nghẽn

Triệu chứng: Nuốt thao tác·rollback, Tua nhanh · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Slow start sau thời gian nhàn rỗi Slow start after idle

Khi kết nối nhàn rỗi một lúc, TCP thu nhỏ lại cửa sổ tắc nghẽn (lượng dữ liệu gửi được trong một lần), nên khi đột ngột gửi dữ liệu lớn, TCP phải chia ra gửi nhiều lượt.

Vì sao: Gửi dữ liệu lớn (ví dụ khi vào thị trấn) qua một kết nối đang nhàn rỗi → Dẫn đến: Cửa sổ tắc nghẽn đã bị thu nhỏ nên dữ liệu bị chia ra gửi qua nhiều lượt khứ hồi → Trên màn hình: Ngay sau khi vào, nhân vật và NPC xung quanh hiện ra trễ vài lượt khứ hồi (server càng xa càng dễ thấy)

Triệu chứng: Trễ thao tác, Không hiển thị·đối tượng ma · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Lượng gửi giảm mạnh do kiểm soát tắc nghẽn Congestion control backoff

TCP coi mất gói là tín hiệu tắc nghẽn và giảm tốc độ gửi 30–50%. Mất gói do Wi-Fi cũng bị xử lý y như vậy.

Vì sao: Có chút mất gói trên Wi-Fi hoặc đường truyền đúng lúc cần gửi nhiều dữ liệu → Dẫn đến: TCP giảm mạnh tốc độ gửi rồi hồi phục chậm (CUBIC, thuật toán mặc định của Linux và Windows, giảm 30%) → Trên màn hình: Ở nơi đông người, bản cập nhật bị dồn lại, gây tua nhanh và trễ thao tác

Triệu chứng: Tua nhanh, Trễ thao tác · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Mất dữ liệu cuối do đóng cưỡng bức bằng RST SO_LINGER, abrupt RST

Khi server cắt kết nối đột ngột, thông báo cuối cùng hoặc tín hiệu đã lưu xong mà server vừa gửi sẽ bị mất.

Vì sao: Server đóng kết nối kiểu cưỡng bức (RST). Xảy ra khi đặt SO_LINGER là 0 giây, hoặc khi đóng socket trước khi đọc hết dữ liệu đã nhận → Dẫn đến: Lý do kick và dữ liệu cuối cùng còn đang trên đường gửi bị vứt bỏ → Trên màn hình: Thông báo “Kết nối bị đóng do lỗi không xác định” mà không rõ lý do

Triệu chứng: Mất kết nối · Phụ trách chính Phát triển server (Đội phát triển game)

Kiến trúc I/O blocking Blocking I/O model

Với kiến trúc mà thread không làm được việc gì khác trong lúc chờ một socket, người chơi càng đông thì cả hệ thống càng chậm.

Vì sao: Mỗi kết nối tự chờ đọc và ghi của riêng nó → Dẫn đến: Độ trễ của một kết nối lan sang các kết nối khác trên cùng thread → Trên màn hình: Số người chơi đồng thời càng tăng, mọi người càng bị quay chậm và trễ thao tác

Triệu chứng: Quay chậm, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game)

SO_REUSEPORT phân phối bị lệch SO_REUSEPORT imbalance, stuck worker

Khi nhiều tiến trình cùng nhận trên một cổng, kernel dùng hash địa chỉ để gán mỗi kết nối cho một tiến trình và không đổi lại. Nếu một tiến trình bị dừng, chỉ những người được gán vào đó phải chờ.

Vì sao: Gateway hoặc server đăng nhập chạy nhiều tiến trình trên cùng cổng bằng SO_REUSEPORT → Dẫn đến: Dù một tiến trình bị dừng vì GC hoặc quá tải, các kết nối mới và gói UDP đã gán cho nó cũng không chuyển sang tiến trình khác → Trên màn hình: Chỉ một số người không vào được hoặc bị đứng hình. Khi khởi động lại làm thay đổi số tiến trình, một số phiên UDP bị ngắt

Triệu chứng: Không vào được·kẹt loading, Đứng hình, Mất kết nối · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

Lỗi WSAECONNRESET trên socket UDP của Windows WSAECONNRESET on a Windows UDP socket

Khi server Windows gửi UDP tới một client đã rời đi, thông báo “không tới được cổng” (ICMP) sẽ gửi về. Thông báo này khiến lời gọi nhận tiếp theo kết thúc bằng lỗi; nếu code server coi lỗi đó là bản thân socket bị hỏng, mọi người dùng socket đó đều bị ảnh hưởng.

Vì sao: Server tiếp tục gửi UDP tới địa chỉ của client vừa thoát, và thông báo “không tới được cổng” (ICMP) gửi về → Dẫn đến: Windows cho lời gọi nhận tiếp theo kết thúc bằng lỗi WSAECONNRESET (10054), và code server ngừng nhận hoặc đóng socket → Trên màn hình: Mọi người chơi đang dùng socket đó cùng lúc bị đứng hình hoặc mất kết nối

Triệu chứng: Mất kết nối, Đứng hình · Phụ trách chính Phát triển server (Đội phát triển game)

Tiến trình game phía server: tick và thread

Đây là chương trình thực sự tính toán logic game. Di chuyển, chiến đấu, AI của quái, tính toán tầm nhìn, broadcast đều phải xong trong một lần “tick”. Người tụ lại một chỗ càng đông, khối lượng tính toán tầm nhìn và số gói tin phải gửi càng tăng theo bình phương số người.

Server tính trạng thái game theo khoảng cách tick cố định. Với server 20 tick, cứ 50 ms một lần, và trong khoảng đó server phải áp dụng input của mọi người chơi, di chuyển quái, tính xem ai nhìn thấy ai (tầm nhìn, AOI), rồi gửi những thay đổi cho tất cả những ai nhìn thấy. 50 ms này là tick budget. Vượt budget thì tick sau bị trễ. Server mỗi tick chỉ cho thời gian trong game tiến một lượng cố định thì toàn bộ thời gian trong game trôi chậm lại (quay chậm); server cho thời gian tiến một lượt đúng bằng thời gian thực đã trôi qua thì giữ được tốc độ, nhưng gói tin thưa đi nên bị giật khựng và dịch chuyển tức thời. Dù theo cách nào, phản hồi cũng chậm đi. Nếu một thread game phụ trách cả server (kênh) thì mọi người trên server đó cùng gặp; nếu chia thread theo khu vực thì những người trong khu vực đó cùng gặp.

Vấn đề nằm ở số người. Nếu so từng cặp với nhau, 100 người phải xét khoảng 10.000 lần, 1.000 người khoảng 1.000.000 lần mỗi tick. Vì thế server chia bản đồ thành lưới (grid) và chỉ so các ô (cell) gần nhau, nhưng khi mọi người dồn về gần một ô như lúc đánh world boss, công thành chiến hay sự kiện ở quảng trường làng, hiệu quả của lưới giảm đi và khối lượng tính toán cùng dữ liệu phải gửi bùng nổ. Thêm vào đó là lock, khi nhiều thread cùng chờ một dữ liệu, và gọi đồng bộ, khi thread chờ phản hồi của DB giữa chừng tick; trong lúc chờ, mọi người do thread đó phụ trách đều đứng lại.

So sánh

Tick của server giống như nhịp của nhạc trưởng. Dàn nhạc (người chơi) càng đông, số bản nhạc phải lo trong một nhịp càng nhiều, và lỡ nhịp thì cả bản nhạc chậm lại. Nếu có người bỏ đi xuống kho (DB) tìm một tờ nhạc thì mọi người phải chờ người đó.

Các nguyên nhân gây lag ở tầng này

Vượt tick budget Tick overrun

Khi khối lượng việc trong một tick vượt budget, chu kỳ tick của server bị kéo dài, và cả khu vực đó chạy chậm lại hoặc giật khựng.

Vì sao: Việc cần xử lý trong một tick (ví dụ 50 ms) vượt budget → Dẫn đến: Trạng thái game lẽ ra được tính 20 lần trong 1 giây chỉ được tính 8 lần → Trên màn hình: Cả khu vực bị quay chậm (tùy thiết kế server có thể là giật khựng), skill phản hồi chậm

Triệu chứng: Quay chậm, Trễ thao tác, Giật khựng · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

Tính toán tầm nhìn (AOI) bùng nổ (N²) Area-of-interest explosion

Nếu so sánh mọi người với nhau để xem ai thấy được ai, số người tăng 10 lần thì khối lượng tính toán tăng 100 lần.

Vì sao: So khoảng cách giữa mọi nhân vật với nhau, hoặc dù đã chia lưới (grid) vẫn có hàng trăm người dồn quanh một ô → Dẫn đến: 100 người thì khoảng 10.000 lần so sánh, 1.000 người thì khoảng 1 triệu lần → Trên màn hình: Ở nơi đông người như world boss hay công thành chiến, tick tăng vọt, gây quay chậm và giật khựng

Triệu chứng: Quay chậm, Giật khựng · Phụ trách chính Phát triển server (Đội phát triển game)

Broadcast bùng nổ Broadcast fan-out (N×N)

Gửi chuyển động của một người cho tất cả những ai nhìn thấy người đó thì số bản cập nhật phải gửi tăng theo bình phương số người tụ tập.

Vì sao: Thay đổi của một người được gửi cho mọi người nhìn thấy người đó → Dẫn đến: 1.000 người cùng nhìn thấy nhau thì mỗi tick có 1 triệu bản cập nhật → Trên màn hình: Hàng đợi gửi và băng thông bão hòa, gây trễ và mất gói (trễ thao tác, tua nhanh, dịch chuyển tức thời)

Triệu chứng: Trễ thao tác, Dịch chuyển tức thời, Tua nhanh · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

Quá tải khu vực chạy trên một thread (hotspot) Single-threaded hot zone

Với kiến trúc mỗi khu vực do một thread phụ trách, khi người chơi dồn vào một chỗ, chỉ một core đó lên 100%.

Vì sao: Mỗi khu vực (kênh) do một thread phụ trách → Dẫn đến: Người chơi dồn vào một chỗ thì chỉ core đó bão hòa, các core còn lại vẫn dư → Trên màn hình: Chỉ khu vực đó bị lag, các khu vực khác vẫn bình thường

Triệu chứng: Quay chậm, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

Tranh chấp lock Lock contention

Khi nhiều thread cùng chờ một lock để ghi cùng một dữ liệu, dù có thêm thread thì mỗi lúc cũng chỉ một thread chạy.

Vì sao: Nhiều thread cùng lúc dùng dữ liệu chung, như sàn đấu giá hoặc kho bang hội → Dẫn đến: Các thread còn lại phải chờ đến khi thread đang giữ lock làm xong → Trên màn hình: Chỉ một số tính năng bị chậm, nặng thì cả tick bị trễ

Triệu chứng: Trễ thao tác, Đứng hình · Phụ trách chính Phát triển server (Đội phát triển game)

Deadlock Deadlock

Khi hai thread chờ lock mà bên kia đang giữ, cả hai sẽ đứng mãi mãi.

Vì sao: Thread A giữ lock 1 và chờ lock 2, B giữ lock 2 và chờ lock 1 → Dẫn đến: Cả hai đứng mãi mãi, các thread liên quan cũng lần lượt đứng theo → Trên màn hình: Cả server ngừng hoạt động, watchdog khởi động lại nên mọi người đều mất kết nối

Triệu chứng: Đứng hình, Mất kết nối · Phụ trách chính Phát triển server (Đội phát triển game)

Gọi đồng bộ (blocking) trên game thread Synchronous DB / file I/O on the game loop

Nếu giữa tick mà phải chờ phản hồi DB hoặc ghi file, mọi diễn biến game trên server dừng lại đúng khoảng thời gian đó.

Vì sao: Trong tick phải chờ truy vấn và lưu DB, ghi log, gọi API bên ngoài → Dẫn đến: DB mất 100 ms thì tick cũng dừng 100 ms → Trên màn hình: Mỗi lần DB hoặc ổ đĩa chậm đi, cả bản đồ lại khựng

Triệu chứng: Đứng hình, Giật khựng · Phụ trách chính Phát triển server (Đội phát triển game)

Hàng đợi message bị dồn ứ Mailbox / job queue backlog

Khi yêu cầu đến nhanh hơn tốc độ xử lý và dồn vào hàng đợi, các yêu cầu phía sau vài giây sau mới được xử lý hoặc bị bỏ.

Vì sao: Yêu cầu đến nhanh hơn tốc độ xử lý → Dẫn đến: Hàng đợi dài ra, vượt giới hạn thì bị bỏ → Trên màn hình: Skill và giao dịch phản hồi chậm hoặc bị nuốt

Triệu chứng: Trễ thao tác, Nuốt thao tác·rollback · Phụ trách chính Phát triển server (Đội phát triển game)

Timer kích hoạt dồn cùng lúc Synchronized timers

Khi mọi lượt respawn quái, mọi buff hết hạn và phần thưởng lúc tròn giờ dồn vào cùng một tick, riêng tick đó nặng lên gấp hàng chục lần.

Vì sao: Timer respawn, hết hạn, phần thưởng và tự động lưu được đặt trùng một thời điểm → Dẫn đến: Riêng tick đó phải làm lượng việc gấp hàng chục lần bình thường → Trên màn hình: Cứ đến giờ đã định là khựng một lần

Triệu chứng: Đứng hình, Giật khựng · Phụ trách chính Phát triển server (Đội phát triển game)

Tìm đường (pathfinding) dồn dập Pathfinding storms

Hàng trăm con quái cùng lúc đuổi theo người chơi và tính đường đi thì tốn rất nhiều CPU.

Vì sao: Gom quái hoặc spawn quy mô lớn khiến nhiều quái cùng lúc đuổi theo người chơi → Dẫn đến: Mỗi con quái tự chạy tìm đường → Trên màn hình: Chỉ bãi săn đó bị quay chậm

Triệu chứng: Quay chậm · Phụ trách chính Phát triển server (Đội phát triển game)

Chi phí serialize và nén Serialization / compression cost

Việc chuyển dữ liệu cần gửi thành byte và nén cũng tốn CPU, và khi đông người, chi phí này tăng vọt.

Vì sao: Mỗi bản cập nhật đều phải chuyển struct thành byte rồi nén → Dẫn đến: Chi phí tăng theo bình phương số người → Trên màn hình: Dữ liệu gửi đi trễ, gây trễ thao tác

Triệu chứng: Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game)

Server crash Server process crash

Khi tiến trình server chết vì một lỗi không được xử lý, mọi người trên server đó mất kết nối cùng lúc.

Vì sao: Lỗi nghiêm trọng như tham chiếu tới thứ không tồn tại (null reference), dữ liệu sai, hết bộ nhớ → Dẫn đến: Tiến trình server (hoặc zone) kết thúc → Trên màn hình: Mọi người cùng mất kết nối, tiến độ từ lần lưu cuối có thể bị rollback

Triệu chứng: Mất kết nối, Nuốt thao tác·rollback · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

Cạn thread pool Thread pool starvation

Khi mọi worker thread xử lý việc đều bị kẹt ở các việc chậm, yêu cầu mới chỉ biết chờ vô thời hạn.

Vì sao: Các worker thread bị kẹt chờ phản hồi từ API bên ngoài hoặc DB → Dẫn đến: Yêu cầu mới không còn thread nào để nhận → Trên màn hình: Kẹt loading ở một số tính năng như đăng nhập hoặc cửa hàng

Triệu chứng: Không vào được·kẹt loading, Trễ thao tác, Đứng hình · Phụ trách chính Phát triển server (Đội phát triển game)

Vòng lặp vô hạn và logic chạy mất kiểm soát Infinite loop / runaway logic

Khi một bug khiến tick không bao giờ kết thúc, server bị treo và watchdog buộc khởi động lại.

Vì sao: Vòng lặp không kết thúc vì điều kiện sai, hoặc đệ quy mất kiểm soát → Dẫn đến: Tick không kết thúc nên server bị treo → Trên màn hình: Đứng hình rồi mọi người đều mất kết nối

Triệu chứng: Đứng hình, Mất kết nối · Phụ trách chính Phát triển server (Đội phát triển game)

Giao tranh dồn vào một mục tiêu (world boss) Hot entity / combat event fan-out

Khi hàng trăm người cùng đánh một boss, phần tính toán cho một con boss dồn vào một chỗ, và thông tin đòn đánh được gửi cho mọi người đang nhìn thấy.

Vì sao: Hàng trăm người liên tục dùng skill, buff, debuff lên một con boss → Dẫn đến: Việc tính máu, danh sách aggro và debuff của boss dồn vào một chỗ, và mỗi đòn đánh đều gửi gói số sát thương và hiệu ứng cho mọi người đang nhìn thấy → Trên màn hình: Skill trúng trễ và số sát thương hiện dồn một lượt, chỉ quanh boss bị quay chậm

Triệu chứng: Trễ thao tác, Tua nhanh, Quay chậm · Phụ trách chính Phát triển server (Đội phát triển game)

Spawn dồn dập khi vào khu vực đông người Spawn burst when entering a crowd

Khi bạn teleport vào một thị trấn chật kín người, server phải gửi cùng lúc ngoại hình, trang bị và trạng thái của hàng trăm người vừa lọt vào tầm nhìn.

Vì sao: Đột ngột xuất hiện ở nơi đông người do teleport, đăng nhập hoặc chuyển kênh → Dẫn đến: Toàn bộ thông tin của hàng trăm người được tạo và gửi trong một lần, PC của bạn cũng phải tải tất cả cùng lúc → Trên màn hình: Vừa đến nơi thì đứng hình một chút, nhân vật hiện ra trễ từng người một và thao tác bị trễ

Triệu chứng: Đứng hình, Trễ thao tác, Tua nhanh · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Đối tượng tích tụ (vật phẩm và vật triệu hồi không được dọn) Entity / timer buildup over uptime

Vật phẩm rơi trên đất, vật triệu hồi, timer đã xong lẽ ra phải biến mất. Nếu chúng không được dọn mà cứ tích tụ, server chạy càng lâu thì mỗi tick càng nhiều việc.

Vì sao: Vật phẩm rơi trên đất, vật triệu hồi, timer đã hết hạn, dữ liệu tổ đội trống không được xóa kịp thời → Dẫn đến: Danh sách phải duyệt mỗi tick dài thêm từng ngày → Trên màn hình: Ngay sau bảo trì vẫn bình thường, vài ngày sau chỉ server hoặc khu vực đó ngày càng ì

Triệu chứng: Quay chậm, Giật khựng, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game)

Bản cập nhật làm thay đổi mô hình lưu lượng Patch changes traffic pattern

Khi nội dung, hiệu ứng hoặc trường đồng bộ mới làm tăng kích thước và tần suất gói tin, server đang chạy tốt bắt đầu chạm giới hạn MTU, băng thông và số gói kể từ sau bản cập nhật.

Vì sao: Bản cập nhật thêm hiệu ứng skill mới, trường đồng bộ, thông tin vật phẩm, khiến gói tin to hơn hoặc dày hơn → Dẫn đến: Gói lớn vượt MTU nên bị phân mảnh, còn lượng tăng thêm chạm giới hạn băng thông, giới hạn PPS của cloud và bộ đệm gửi → Trên màn hình: Từ ngay sau bản cập nhật, ở nơi đông người bị dịch chuyển tức thời, nuốt skill, trễ thao tác. Hạ tầng không thay đổi gì mà mất gói lại tăng

Triệu chứng: Dịch chuyển tức thời, Nuốt thao tác·rollback, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng), Hạ tầng mạng (Đội hạ tầng)

Bộ nhớ

Mọi thứ server ghi nhớ, tức nhân vật, quái, vật phẩm, bản đồ, đều nằm trong bộ nhớ. Bản thân bộ nhớ nhanh, nhưng lag xuất hiện ngay khi server dừng vì GC (thu hồi bộ nhớ không còn dùng), khi bộ nhớ bị rò rỉ dần (rò rỉ bộ nhớ), hoặc khi thiếu bộ nhớ đến mức phải swap (chuyển một phần bộ nhớ ra ổ đĩa).

Các ngôn ngữ tự quản lý bộ nhớ như Java, C#, Go có bộ thu gom rác (GC) gom và thu hồi phần bộ nhớ đã dùng xong. Tùy cách GC hoạt động, nó có thể dừng mọi thread trong chốc lát. Nếu GC toàn bộ heap (vùng bộ nhớ chương trình xin cấp trong lúc chạy) một lượt, dữ liệu còn sống càng nhiều thì càng lâu, có thể từ hàng trăm ms đến vài giây. GC đời mới như ZGC rút thời gian dừng xuống dưới 1 ms nhưng tốn thêm CPU và bộ nhớ. Server C++ không có GC nhưng lại khổ vì rò rỉ (bộ nhớ quên giải phóng cứ tích dần) và phân mảnh (khoảng trống bị chia vụn nên không dùng được cho khối lớn). Ngay cả khi có GC, nếu đối tượng đã dùng xong vẫn bị tham chiếu ở đâu đó thì rò rỉ vẫn xảy ra y như vậy.

Một lý do khác khiến bộ nhớ chậm là phân cấp bộ nhớ (nơi lưu trữ cách CPU bao xa). Cache ngay cạnh CPU mất 1 ns, RAM mất 100 ns, còn đọc lại phần bộ nhớ đã đẩy ra ổ đĩa (swap) thì mất hơn 1.000 lần so với RAM. Hãy thử phóng chênh lệch này thành thời gian của con người trong bảng “Cảm nhận con số” bên dưới.

So sánh

Bộ nhớ giống như bàn sơ chế của đầu bếp. Nguyên liệu nằm trong tầm tay (cache) thì nhanh, phải ra tủ lạnh (RAM) thì hơi chậm, còn khi bàn đầy phải cất nguyên liệu vào kho (ổ đĩa, swap) thì mỗi lần lấy ra mất rất lâu. Trong lúc rửa bát (GC) thì phải ngừng nấu.

Các nguyên nhân gây lag ở tầng này

GC dừng toàn bộ server Stop-the-world GC pause

Trong lúc server Java hoặc C# dừng mọi thread để thu gom rác (stop-the-world), toàn bộ server đứng lại.

Vì sao: Heap đầy nên GC bắt đầu chạy → Dẫn đến: Dừng mọi thread game để thu gom (càng nhiều dữ liệu còn sống thì càng lâu) → Trên màn hình: Mọi người chơi trên server cùng lúc đứng hình rồi tua nhanh

Triệu chứng: Đứng hình, Tua nhanh · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

GC pause của script engine Scripting VM GC (Lua, etc.)

Ngay cả server viết bằng C++, nếu nhiệm vụ, AI và skill chạy bằng script như Lua thì trong lúc GC của script engine chạy, zone đó sẽ bị dừng.

Vì sao: Ở mỗi zone, script engine chạy nhiệm vụ, AI và sự kiện, tạo ra một lượng lớn đối tượng tạm → Dẫn đến: GC của script engine thu gom dồn một lượng lớn trong một lần, tick của zone đó bị dừng → Trên màn hình: Chỉ khựng theo chu kỳ ở một zone nhất định hoặc trong một sự kiện nhất định

Triệu chứng: Giật khựng, Đứng hình · Phụ trách chính Phát triển server (Đội phát triển game)

Cấp phát bộ nhớ dồn dập Allocation storms

Khi sự kiện tạo ra hàng loạt đối tượng tạm, GC phải chạy thường xuyên hơn nhiều so với bình thường.

Vì sao: Vật phẩm rơi ra, log chiến đấu và phần thưởng sự kiện làm số đối tượng tạm tăng vọt → Dẫn đến: GC chạy dày gấp mấy lần, các đối tượng chưa kịp bị bỏ đi bị chuyển sang vùng Old, khiến Full GC cũng đến sớm hơn → Trên màn hình: Chỉ khựng theo chu kỳ trong lúc có sự kiện

Triệu chứng: Giật khựng, Đứng hình · Phụ trách chính Phát triển server (Đội phát triển game)

Rò rỉ bộ nhớ Memory leak

Bộ nhớ không được giải phóng tích tụ dần, vài ngày sau dẫn tới GC chạy dồn dập, swap hoặc tiến trình bị buộc kết thúc.

Vì sao: Dữ liệu của nhân vật đã thoát game và các event handler không được giải phóng → Dẫn đến: Bộ nhớ trống giảm dần qua nhiều ngày → Trên màn hình: Ngay sau bảo trì thì bình thường, càng ngày càng lag, cuối cùng server sập

Triệu chứng: Quay chậm, Đứng hình, Mất kết nối · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

GC thrashing (heap còn ít chỗ trống) GC thrashing (heap nearly full)

Khi dữ liệu còn sống gần chạm giới hạn heap, GC chạy xong cũng gần như không thu hồi được gì, nên GC cứ lặp lại không ngừng.

Vì sao: Số người tăng do sự kiện hoặc rò rỉ bộ nhớ làm dữ liệu còn sống lấp gần tới giới hạn heap → Dẫn đến: GC chỉ thu hồi được một ít nên lập tức lại chạy Full GC, phần lớn CPU bị GC chiếm → Trên màn hình: Cả server lặp đi lặp lại quay chậm và đứng hình trong vài phút rồi sập vì hết bộ nhớ

Triệu chứng: Quay chậm, Đứng hình, Mất kết nối · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

Swap Swapping

Khi thiếu bộ nhớ, OS đẩy một phần xuống ổ đĩa. Sau đó, mỗi lần cần dùng phần bộ nhớ ấy, server phải chờ ổ đĩa chậm hơn RAM trên 1.000 lần.

Vì sao: Bộ nhớ đang dùng vượt quá RAM thực → Dẫn đến: OS đẩy một phần xuống ổ đĩa, khi cần thì đọc lên lại → Trên màn hình: Tick tăng vọt lên vài trăm ms, mọi người chơi trên server bị quay chậm và đứng hình

Triệu chứng: Quay chậm, Đứng hình · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Cache miss CPU cache misses

Khi dữ liệu nằm rải rác khắp bộ nhớ, lần nào CPU cũng phải đi tới tận RAM vốn chậm hơn và chờ.

Vì sao: Đối tượng nằm rải rác, nối với nhau bằng con trỏ, và bị truy cập không theo thứ tự → Dẫn đến: Dữ liệu không có trong cache CPU nên lần nào cũng phải đọc từ RAM (chậm hơn khoảng 100 lần) → Trên màn hình: Cùng một việc mà chi phí mỗi tick tăng gấp mấy lần, nặng thì quay chậm

Triệu chứng: Quay chậm · Phụ trách chính Phát triển server (Đội phát triển game)

Phân mảnh bộ nhớ Heap fragmentation

Cấp phát và giải phóng lặp đi lặp lại làm vùng trống bị chia vụn, khiến tiến trình chiếm nhiều bộ nhớ hơn hẳn lượng thực sự dùng.

Vì sao: Nhiều thread cấp phát và giải phóng các vùng nhớ đủ mọi kích thước trong thời gian dài → Dẫn đến: Vùng trống vụn rải rác nên không trả lại được cho OS, mức dùng cứ tăng như bị rò rỉ → Trên màn hình: Càng chạy lâu càng chậm vì swap hoặc thiếu bộ nhớ, rồi bị buộc kết thúc

Triệu chứng: Quay chậm, Mất kết nối · Phụ trách chính Phát triển server (Đội phát triển game)

Truy cập bộ nhớ NUMA từ xa Remote NUMA access

Trên server có hai CPU, nếu tiến trình dùng bộ nhớ gắn với CPU bên kia thì truy cập bộ nhớ chậm đi.

Vì sao: Thread và bộ nhớ nằm trên hai socket CPU khác nhau → Dẫn đến: Truy cập bộ nhớ chậm đi (tùy thiết bị, 1,5–2 lần) → Trên màn hình: Cùng cấu hình mà mỗi tiến trình cho hiệu năng khác nhau

Triệu chứng: Quay chậm · Phụ trách chính Hạ tầng server (Đội hạ tầng)

Ổ đĩa

Log, dữ liệu lưu nhân vật, dữ liệu bản đồ, file DB đều nằm trên ổ đĩa. Ổ đĩa chậm hơn bộ nhớ từ hàng trăm lần (SSD) đến 100.000 lần (HDD), nên nếu server game được thiết kế phải chờ ổ đĩa thì ổ đĩa vừa bận là game cũng đứng theo.

Hiệu năng ổ đĩa được đo bằng “đọc ghi được bao nhiêu lần trong 1 giây” (IOPS). HDD đời cũ chừng hơn 150 lần, SSD từ vài chục nghìn đến vài trăm nghìn lần. Ổ đĩa trên cloud có giới hạn tùy số tiền bỏ ra (gp3 mặc định của AWS là 3.000 lần). Một số ổ đĩa cloud và cấu hình server nhỏ có burst credit, cho phép chạy hiệu năng cao hơn mức thường trong một lúc, nhưng khi giờ bận kéo dài, credit cạn và tốc độ tụt đột ngột. Những báo cáo kiểu “tối nào cũng vậy, chơi được vài tiếng là lag” có dạng này.

Mấu chốt là ai phải chờ. Thao tác ghi file thông thường được OS nhận vào bộ nhớ trước rồi mới ghi xuống ổ đĩa sau, nên thường xong ngay. Vấn đề là khi chương trình yêu cầu chờ “đến khi thực sự ghi xong xuống ổ đĩa” (fsync), hoặc khi phần bộ nhớ OS dành để nhận dữ liệu ghi đã đầy. Lúc đó nếu thread game trực tiếp chờ (đồng bộ), ổ đĩa chậm 100 ms thì tick cũng đứng 100 ms. Nếu giao việc ghi cho một thread riêng (bất đồng bộ) thì game không đứng, nhưng nếu server đột ngột chết thì phần chưa kịp ghi có thể mất (nuốt thao tác·rollback).

So sánh

Ổ đĩa là nhà kho, IOPS là số cửa của nhà kho. Ít cửa thì người ra vào lấy hàng phải xếp hàng. Burst credit là thể lực để chạy nước rút trong chốc lát, dùng hết thì quay về tốc độ đi bộ.

Các nguyên nhân gây lag ở tầng này

Ghi log đồng bộ Synchronous logging

Nếu thread game chờ ổ đĩa ghi xong từng dòng log, thì lúc ổ đĩa bận, game cũng bị dừng theo.

Vì sao: Thread game ghi log chiến đấu và log giao dịch thẳng vào file → Dẫn đến: Khi yêu cầu lưu chắc chắn (fsync), hoặc khi bộ đệm ghi của OS (page cache) chạm giới hạn, một lần ghi lúc ổ đĩa bận mất tới vài chục ms → Trên màn hình: Khựng trong những trận đánh sinh nhiều log

Triệu chứng: Giật khựng, Đứng hình · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

fsync dồn dập fsync storms

Mỗi yêu cầu ghi dữ liệu xuống ổ đĩa “chắc chắn” mất từ 0,1 ms đến vài chục ms tùy ổ đĩa, và khi các yêu cầu dồn lại thì hàng đợi dài ra.

Vì sao: Lưu định kỳ và đợt đăng xuất ồ ạt làm yêu cầu ghi chắc chắn dồn lại → Dẫn đến: Hàng đợi ổ đĩa dài ra → Trên màn hình: Cứ đến giờ lưu là lag, đăng xuất và chuyển kênh bị chậm

Triệu chứng: Giật khựng, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng), Hạ tầng DB (Đội hạ tầng)

Cạn burst credit của ổ đĩa cloud Burst credit depletion

Một số ổ đĩa cloud và cấu hình server nhỏ có burst credit cho phép tạm chạy nhanh hơn mức cơ bản. Khi giờ bận kéo dài làm credit cạn, tốc độ đột ngột tụt xuống.

Vì sao: Dùng vượt hiệu năng cơ bản trong thời gian dài → Dẫn đến: Burst credit cạn, tụt thẳng về hiệu năng cơ bản → Trên màn hình: Tối nào cũng vậy, sau vài giờ thì bắt đầu lag

Triệu chứng: Giật khựng, Quay chậm, Trễ thao tác · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Hạ tầng DB (Đội hạ tầng)

Chạm giới hạn IOPS, hàng đợi bão hòa IOPS limit / queue saturation

Khi vượt số yêu cầu ổ đĩa xử lý được trong 1 giây, hàng đợi dài ra và độ trễ tăng vọt.

Vì sao: Yêu cầu đọc, ghi tiến sát khả năng xử lý của ổ đĩa → Dẫn đến: Hàng đợi dài ra (thường tăng vọt khi mức sử dụng từ 90% trở lên) → Trên màn hình: Lưu và loading bị chậm, nếu là lời gọi đồng bộ thì đứng hình

Triệu chứng: Trễ thao tác, Đứng hình · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game), Hạ tầng DB (Đội hạ tầng)

Ổ đĩa đầy Disk full

Khi log và dump tích tụ làm ổ đĩa đầy, thao tác ghi thất bại, và nếu không có phương án dự phòng thì server sập.

Vì sao: Log, dump và file tạm tích tụ tới 100% → Dẫn đến: Ghi thất bại. Không có xử lý lỗi thì crash, có thì lưu thất bại → Trên màn hình: Mất kết nối, tiến độ chơi bị rollback

Triệu chứng: Mất kết nối, Nuốt thao tác·rollback · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Hạ tầng DB (Đội hạ tầng), Phát triển server (Đội phát triển game)

Tác vụ sao lưu, nén, quét Backup / compression / scans

Khi sao lưu lúc rạng sáng, nén log hoặc quét bảo mật chiếm trọn ổ đĩa, việc đọc ghi của server game bị dồn lại.

Vì sao: Tác vụ sao lưu, nén đã lên lịch bắt đầu chạy → Dẫn đến: Chiếm phần lớn băng thông và IOPS của ổ đĩa → Trên màn hình: Ngày nào cũng lag vào cùng một giờ

Triệu chứng: Giật khựng, Trễ thao tác · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Hạ tầng DB (Đội hạ tầng)

Lazy loading phía server Lazy loading on the server

Nếu server đợi đến lần đầu có yêu cầu mới đọc dữ liệu phó bản hay bản đồ từ ổ đĩa, thì trong tick đó mọi người đều bị dừng.

Vì sao: Có người vào một phó bản hoặc khu vực lần đầu → Dẫn đến: Server đọc dữ liệu từ ổ đĩa ngay trên thread game → Trên màn hình: Mọi người trên server đó đứng hình trong chốc lát

Triệu chứng: Đứng hình · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

Ghi core dump Core dump writing

Khi server sập, việc ghi vài GB bộ nhớ xuống ổ đĩa có thể làm việc khởi động lại chậm mất vài phút.

Vì sao: Server crash, ghi toàn bộ bộ nhớ ra file → Dẫn đến: Không thể khởi động lại trong lúc ghi vài GB → Trên màn hình: Server sập làm mất kết nối, sau đó rất lâu vẫn không vào được

Triệu chứng: Không vào được·kẹt loading · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Độ trễ seek của HDD HDD seek latency

HDD phải di chuyển đầu đọc trên đĩa từ (seek), nên mỗi lần đọc ghi dữ liệu nằm rải rác mất gần 10 ms.

Vì sao: Server cũ hoặc storage giá rẻ dùng HDD → Dẫn đến: Mỗi lần đọc ghi rải rác mất khoảng 10 ms → Trên màn hình: Lưu và loading chậm nói chung

Triệu chứng: Trễ thao tác · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Hạ tầng DB (Đội hạ tầng), Phát triển server (Đội phát triển game)

Cơ sở dữ liệu

Đây là nơi chứa những thứ tuyệt đối không được mất như nhân vật, vật phẩm, tiền tệ trong game, lịch sử giao dịch. DB chậm thì chiến đấu vẫn bình thường nhưng vật phẩm về chậm, giao dịch thất bại, đăng nhập mãi không xong. Nếu server game được thiết kế phải chờ DB thì cả bản đồ sẽ đứng.

Server game tạo sẵn vài kết nối tới DB (connection pool) và dùng luân phiên. Một query (yêu cầu gửi tới DB) chạy lâu thì kết nối đó bị chiếm suốt, và khi mọi kết nối trong pool đều đang bận thì các yêu cầu còn lại phải chờ trong hàng đợi. Có hai lý do phổ biến khiến query chậm: không có index (giống mục lục của sách) nên phải đọc toàn bộ bảng (full scan), hoặc nhiều yêu cầu cùng sửa một dòng một lúc nên phải chờ khóa.

Để đáng tin cậy và nhận được nhiều yêu cầu, DB dùng nhiều cơ chế: bản sao (replica) để chia tải đọc, DB dự phòng để chuyển sang khi có sự cố, checkpoint để định kỳ ghi dồn phần thay đổi xuống ổ đĩa. Khi checkpoint dồn lại, DB chậm đi một lúc. Bản sao bị trễ thì sinh ra “vật phẩm vừa mua không thấy đâu”, còn nếu chuyển sang DB dự phòng trong lúc replication đang trễ thì sinh ra “vào lại game thì trạng thái quay về lúc nãy”, đều là triệu chứng nuốt thao tác·rollback. Nếu server game chỉ lưu nhân vật vài phút một lần, khi server chết sẽ thành “bị quay về 10 phút trước”.

So sánh

DB giống như quầy ngân hàng. Số quầy (connection pool) có hạn, và nếu một yêu cầu phải lục lại toàn bộ sổ sách (full scan) thì mọi yêu cầu phía sau đều phải chờ. Nếu ai cũng muốn mở cùng một két sắt (hot row) thì chỉ vào được từng người một.

Các nguyên nhân gây lag ở tầng này

Query không có index Missing index / full table scan

Không có index thì muốn tìm các dòng thỏa điều kiện, DB phải đọc toàn bộ bảng (full scan).

Vì sao: Tính năng mới được triển khai, kèm truy vấn theo điều kiện không có index → Dẫn đến: Quét toàn bộ hàng triệu dòng, một query mất từ vài trăm ms đến vài giây → Trên màn hình: Hộp thư và lịch sử giao dịch tải chậm, kết nối DB bị giữ khiến các yêu cầu khác cũng phải chờ

Triệu chứng: Trễ thao tác, Không vào được·kẹt loading · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng DB (Đội hạ tầng)

Tranh chấp khóa trên hot row Hot row lock contention

Khi ai cũng muốn sửa cùng một dòng (kho bang hội, vật phẩm hot ở nhà đấu giá, bộ đếm toàn server), mỗi lúc chỉ một người lấy được khóa.

Vì sao: Sự kiện hoặc vật phẩm hot làm các lần sửa dồn vào cùng một dòng → Dẫn đến: Các yêu cầu phải chờ đến khi lấy được khóa → Trên màn hình: Giao dịch thất bại, “Vui lòng thử lại sau”, timeout

Triệu chứng: Nuốt thao tác·rollback, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng DB (Đội hạ tầng)

Deadlock trong DB Database deadlock

Khi hai transaction (nhóm thao tác DB được xử lý như một khối) chờ dòng mà bên kia đã khóa, DB buộc phải hủy một bên.

Vì sao: Giao dịch A khóa theo thứ tự vật phẩm→tiền tệ, B khóa theo thứ tự tiền tệ→vật phẩm → Dẫn đến: DB phát hiện deadlock và rollback một bên → Trên màn hình: Giao dịch và chế tạo thỉnh thoảng thất bại, vật phẩm bị trả lại

Triệu chứng: Nuốt thao tác·rollback, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng DB (Đội hạ tầng)

Cạn connection pool Connection pool exhaustion

Số kết nối tạo sẵn tới DB là cố định, nên khi query chậm chiếm giữ kết nối, các yêu cầu còn lại phải chờ.

Vì sao: Query chậm hoặc yêu cầu dồn dập làm mọi kết nối đều đang bận → Dẫn đến: Yêu cầu mới phải chờ đến khi có kết nối rảnh → Trên màn hình: Đăng nhập kẹt loading, lưu chậm, timeout

Triệu chứng: Không vào được·kẹt loading, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng DB (Đội hạ tầng)

Replication lag Replication lag

Khi ghi vào DB chính và đọc từ bản sao, nếu bản sao bị tụt lại phía sau thì nội dung vừa ghi sẽ chưa hiện ra.

Vì sao: Thao tác ghi dồn vào DB chính khiến bản sao tụt lại vài giây → Dẫn đến: Đọc nội dung vừa lưu từ bản sao thì chưa có → Trên màn hình: Vật phẩm vừa mua không thấy đâu, giá trên sàn giao dịch là giá cũ, lỗi phát thưởng trùng

Triệu chứng: Nuốt thao tác·rollback · Phụ trách chính Hạ tầng DB (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Checkpoint, flush log Checkpoint / log flush stalls

Đúng lúc DB định kỳ ghi dồn các thay đổi trong bộ nhớ xuống ổ đĩa, query chậm đi.

Vì sao: Thay đổi tích tụ và định kỳ được ghi xuống ổ đĩa → Dẫn đến: Lúc đó ổ đĩa bận, query bị trễ → Trên màn hình: Lưu và loading chậm đi theo chu kỳ

Triệu chứng: Trễ thao tác, Giật khựng · Phụ trách chính Hạ tầng DB (Đội hạ tầng)

Cache lạnh (ngay sau khởi động lại) Cold buffer pool after restart

Khi DB khởi động lại, cache trong bộ nhớ trống trơn, nên một thời gian mọi truy vấn đều phải đọc từ ổ đĩa.

Vì sao: DB khởi động lại trong đợt bảo trì → Dẫn đến: Dữ liệu hay dùng không có trong bộ nhớ nên phải đọc từ ổ đĩa → Trên màn hình: Ngay sau bảo trì, đăng nhập và loading chậm một thời gian

Triệu chứng: Không vào được·kẹt loading, Trễ thao tác · Phụ trách chính Hạ tầng DB (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Đăng nhập ồ ạt và query N+1 Login storm, N+1 queries

Nếu tải một nhân vật mà phải truy vấn riêng lẻ vài chục lần, thì vài chục nghìn người đăng nhập cùng lúc sẽ thành hàng triệu query.

Vì sao: Khi tải nhân vật, truy vấn vật phẩm, skill, nhiệm vụ riêng từng thứ một → Dẫn đến: Ngay sau bảo trì, đăng nhập đồng thời làm số query tăng vọt → Trên màn hình: Đăng nhập kẹt loading, việc lưu của người đang chơi cũng bị dồn lại

Triệu chứng: Không vào được·kẹt loading, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng DB (Đội hạ tầng)

Tác vụ batch khối lượng lớn Batch jobs during service

Nếu chạy tổng hợp bảng xếp hạng, gửi thư hàng loạt hay dọn dữ liệu cũ trong lúc đang vận hành, các tác vụ này sẽ chiếm khóa và ổ đĩa.

Vì sao: Chạy tác vụ khối lượng lớn trong giờ vận hành → Dẫn đến: Khóa phạm vi rộng, chiếm ổ đĩa và CPU → Trên màn hình: Giao dịch và lưu thất bại vào một khung giờ nhất định, loading chậm

Triệu chứng: Trễ thao tác, Nuốt thao tác·rollback · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng DB (Đội hạ tầng)

Failover DB Database failover

Trong lúc DB chính chết và chuyển sang DB dự phòng, không ghi được dữ liệu, và phần dữ liệu cuối cùng chưa kịp replicate có thể bị mất.

Vì sao: DB chính gặp sự cố, DB dự phòng được nâng lên làm DB chính → Dẫn đến: Trong lúc chuyển, không ghi được từ vài giây đến vài phút; nếu replication bất đồng bộ thì dữ liệu chưa replicate có thể mất → Trên màn hình: Mọi thao tác lưu thất bại trong chốc lát, vật phẩm và điểm kinh nghiệm bị rollback

Triệu chứng: Nuốt thao tác·rollback, Đứng hình, Mất kết nối, Không vào được·kẹt loading · Phụ trách chính Hạ tầng DB (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Mất tiến độ do chu kỳ lưu dài Periodic save window

Nếu để giảm tải mà vài phút mới lưu một lần, thì khi server sập giữa hai lần lưu, tiến độ chơi sẽ mất.

Vì sao: Trạng thái nhân vật được lưu vài phút một lần → Dẫn đến: Giữa hai lần lưu, server crash hoặc gặp sự cố → Trên màn hình: Vào lại game thì thấy trạng thái của vài phút trước (rollback)

Triệu chứng: Nuốt thao tác·rollback · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng DB (Đội hạ tầng)

Cache stampede Cache stampede / thundering herd

Khi cache của dữ liệu được dùng nhiều hết hạn cùng lúc, hàng nghìn yêu cầu đồng loạt dồn về DB.

Vì sao: Dữ liệu hot lưu trong Redis hoặc tương tự hết hạn cùng lúc → Dẫn đến: Các yêu cầu muốn tạo lại cùng dữ liệu đó đồng loạt dồn về DB → Trên màn hình: DB quá tải khiến nhiều tính năng lần lượt chậm đi hoặc đứng hình

Triệu chứng: Trễ thao tác, Đứng hình, Không vào được·kẹt loading · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng DB (Đội hạ tầng)

Transaction mở quá lâu Long-running transaction / MVCC purge lag

Nếu một transaction mở quá lâu, nó giữ khóa mãi, và DB không dọn (purge) được dữ liệu phiên bản cũ nên toàn bộ hệ thống chậm dần.

Vì sao: Mở transaction rồi chờ phản hồi của server khác, hoặc chạy query tổng hợp dài trên DB chính trong giờ vận hành → Dẫn đến: Khóa đã giữ không được nhả, dữ liệu phiên bản cũ cần dọn cứ tích tụ → Trên màn hình: Tính năng dùng dòng đó bị timeout, việc lưu và truy vấn nói chung chậm dần trong vài giờ

Triệu chứng: Trễ thao tác, Nuốt thao tác·rollback · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng DB (Đội hạ tầng)

Lệnh Redis chậm Redis blocking commands (single-threaded)

Redis xử lý lần lượt từng lệnh một, nên một lệnh chậm sẽ chặn mọi yêu cầu phía sau.

Vì sao: Trong giờ vận hành, dùng KEYS để quét toàn bộ, đọc hoặc xóa trọn một bảng xếp hạng hay danh sách có hàng triệu phần tử → Dẫn đến: Mọi yêu cầu khác phải chờ cho đến khi lệnh đó xong (từ vài chục ms đến vài giây) → Trên màn hình: Các tính năng dùng session, bảng xếp hạng, cache cùng lúc bị khựng, đăng nhập chậm

Triệu chứng: Đứng hình, Trễ thao tác, Không vào được·kẹt loading · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng DB (Đội hạ tầng)

Query chậm do kế hoạch thực thi thay đổi Query plan regression (stats, parameter sniffing)

Code không đổi, nhưng nếu DB đổi cách xử lý cùng một query (kế hoạch thực thi), query hôm qua mất 2 ms thì hôm nay mất vài trăm ms.

Vì sao: Thống kê tự động cập nhật, DB khởi động lại hoặc phân bố dữ liệu thay đổi khiến DB lập lại kế hoạch thực thi → Dẫn đến: Kế hoạch không dùng index được chọn, cùng một query chậm đi vài chục đến vài trăm lần, kết nối DB bị giữ → Trên màn hình: Không hề có triển khai mà một tính năng đột nhiên tải chậm, các yêu cầu khác cũng phải chờ

Triệu chứng: Trễ thao tác, Không vào được·kẹt loading · Phụ trách chính Hạ tầng DB (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Khóa do thay đổi schema (DDL) khi đang vận hành Schema change lock (DDL / metadata lock)

Nếu thêm cột hay index vào bảng trong lúc đang phục vụ, chỉ vì một khóa cần trong chốc lát mà mọi yêu cầu dùng bảng đó có thể phải chờ.

Vì sao: Hotfix thêm cột hoặc index vào bảng đang vận hành → Dẫn đến: Thay đổi schema chờ transaction dài đã mở trước đó, còn mọi yêu cầu đến sau lại chờ thay đổi schema đó → Trên màn hình: Các tính năng dùng bảng đó (túi đồ, hộp thư, v.v.) ngừng phản hồi hoàn toàn rồi timeout

Triệu chứng: Trễ thao tác, Nuốt thao tác·rollback, Không vào được·kẹt loading · Phụ trách chính Hạ tầng DB (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Kiến trúc và vận hành server

MMO ngày nay thường có cấu trúc gồm các server đăng nhập, gateway, bản đồ, phó bản, chat, tổ đội, sàn đấu giá, cache, DB gọi lẫn nhau để vận hành. Sự cố ở một nơi sẽ lan sang những nơi kết nối với nó, và các công việc vận hành như triển khai, mở rộng, bảo trì cũng gây lag.

Chia nhỏ server giúp ngăn sự cố ở một nơi lan ra toàn hệ thống, nhưng đổi lại sinh ra chuỗi gọi (server lần lượt gọi server khác). Ví dụ server game gọi server đấu giá, server đấu giá lại gọi cache và DB. Khi server ở cuối chuỗi chậm đi, các server phía trước cứ chiếm giữ thread và kết nối trong lúc chờ phản hồi, cuối cùng ngay cả những tính năng tưởng không liên quan cũng đứng lại. Hiện tượng này gọi là sự cố dây chuyền, và được ngăn lan rộng bằng timeout và circuit breaker (cơ chế tạm chặn các lời gọi liên tục thất bại).

Công việc vận hành cũng là nguyên nhân gây lag. Khởi động lại khi triển khai bản cập nhật, vài phút để tự động thêm server khi đông người, quá trình chuyển nhân vật sang server khác khi chuyển bản đồ, tải vô hình do bot và macro tạo ra, tất cả đều hiện ra trước mắt người chơi thành “lag”.

So sánh

Kiến trúc server giống như một công ty mà nhiều phòng ban chuyển hồ sơ trình duyệt qua lại. Chỉ cần một phòng ở cuối tuyến duyệt (DB) chậm lại, các phòng phía trước sẽ cầm hồ sơ xếp hàng, cuối cùng mọi việc của công ty đều đứng lại. Timeout là quy định “quá 10 phút không có trả lời thì trả hồ sơ về trước đã”, còn circuit breaker là quy định “nếu cứ bị trả về liên tục thì trong một thời gian không gửi hồ sơ tới phòng đó nữa mà trả lại ngay”.

Các nguyên nhân gây lag ở tầng này

Đi qua gateway hoặc proxy Gateway / proxy hop

Khi đặt một server trung gian giữa client và server game, mỗi lần đi qua nó lại cộng thêm thời gian xử lý, và server đó trở thành điểm lỗi duy nhất (single point of failure).

Vì sao: Cấu trúc client ↔ gateway ↔ server game → Dẫn đến: Server trung gian cộng thêm thời gian xử lý và chờ, khi quá tải thì ảnh hưởng đến tất cả mọi người → Trên màn hình: Ping của mọi người đều tăng, khi gateway gặp sự cố thì toàn bộ người chơi đi qua gateway đó bị mất kết nối

Triệu chứng: Trễ thao tác, Mất kết nối · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng), Phát triển client (Đội phát triển game)

Chuyển zone (chuyển giao giữa các server) Zone / server handoff

Khi nhân vật vào bản đồ hoặc phó bản khác, thông tin nhân vật phải được chuyển sang server khác, và quá trình này có thể bị chậm hoặc thất bại.

Vì sao: Vào phó bản hoặc sang lục địa khác làm đổi server phụ trách → Dẫn đến: Lưu → chuyển → tải; nếu server đích đang đông hoặc không còn instance phó bản trống thì phải chờ → Trên màn hình: Loading lâu, không vào được, mất kết nối giữa lúc chuyển

Triệu chứng: Không vào được·kẹt loading, Đứng hình, Mất kết nối, Kéo ngược · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

Sự cố dây chuyền Cascading failure

Khi một service chậm đi, các server gọi đến nó bị giữ lại để chờ phản hồi, và cả những tính năng không liên quan cũng đứng lại.

Vì sao: Một service như DB hay xác thực bị chậm → Dẫn đến: Thread và kết nối của các server gọi đến bị giữ lại để chờ phản hồi, việc thử lại các yêu cầu thất bại càng làm tăng tải → Trên màn hình: Cả những tính năng tưởng như không liên quan cũng chậm hoặc đứng hết

Triệu chứng: Đứng hình, Trễ thao tác, Không vào được·kẹt loading · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng mạng (Đội hạ tầng)

Sự cố server phụ trợ Auxiliary service outage

Khi một server chạy tách riêng khỏi server game như chat, tổ đội, nhà đấu giá gặp sự cố, chỉ riêng tính năng đó ngừng hoạt động.

Vì sao: Server dành riêng cho một tính năng bị chậm hoặc chết → Dẫn đến: Chỉ yêu cầu của tính năng đó không có phản hồi → Trên màn hình: Không chat được, mời tổ đội không phản hồi, sàn giao dịch loading mãi (chiến đấu vẫn bình thường)

Triệu chứng: Nuốt thao tác·rollback, Không vào được·kẹt loading · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

Triển khai và khởi động lại Deploy / rolling restart

Khi khởi động lại server để cập nhật mà không chuyển kết nối đi nơi khác, những người đang ở server đó bị mất kết nối, đồng thời việc lưu dữ liệu ngay trước khi tắt và việc kết nối lại dồn vào cùng một lúc.

Vì sao: Triển khai hotfix, khởi động lại lần lượt từng server → Dẫn đến: Tắt server mà không chuyển kết nối sang server khác, dữ liệu cần lưu của mọi người chơi trên server đó dồn vào DB → Trên màn hình: Mất kết nối không có thông báo trước, lượng kết nối lại tăng đột biến

Triệu chứng: Mất kết nối, Không vào được·kẹt loading, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

Autoscaling chậm Autoscaling lag

Khi đông người, số server được tự động tăng lên nhưng phải mất vài phút mới sẵn sàng, và trong thời gian đó các server hiện có bị quá tải.

Vì sao: Sự kiện bắt đầu làm lượng kết nối tăng vọt → Dẫn đến: Mất vài phút để server mới bật lên và sẵn sàng → Trên màn hình: Vài phút ngay sau khi sự kiện bắt đầu bị quay chậm, không vào được

Triệu chứng: Quay chậm, Không vào được·kẹt loading · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Quá tải log và giám sát Logging / monitoring overhead

Khi có sự cố, log tăng đột biến, và server gửi log theo kiểu đồng bộ lại càng chậm hơn vì chính log.

Vì sao: Lỗi xảy ra làm lượng log và chỉ số gửi đi tăng đột biến → Dẫn đến: Bộ thu thập log bị dồn việc, server gửi đồng bộ phải chờ → Trên màn hình: Khi có sự cố, giật khựng và đứng hình càng nặng hơn vì log

Triệu chứng: Giật khựng, Đứng hình · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)

Lệch đồng hồ giữa các server Clock skew between servers

Nếu đồng hồ của các server lệch nhau một chút, việc phán định hồi chiêu, buff, thời điểm bắt đầu sự kiện sẽ không khớp giữa các server.

Vì sao: Đồng hồ của server bị ngừng đồng bộ thời gian lệch với server khác từ vài trăm ms đến vài giây → Dẫn đến: Truyền thời điểm tuyệt đối như lúc buff hết hạn giữa các server thì phán định bị lệch → Trên màn hình: Di chuyển sang nơi khác thì buff biến mất hoặc hồi chiêu chạy lại từ đầu

Triệu chứng: Nuốt thao tác·rollback · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)

Quá nhiều macro và bot Bots and macros

Bot gửi yêu cầu thường xuyên hơn người thật rất nhiều, dần chiếm mất năng lực xử lý của server.

Vì sao: Lượng lớn bot kết nối, lặp đi lặp lại săn quái, di chuyển, giao dịch không nghỉ → Dẫn đến: Khối lượng xử lý trên server và tải DB tăng → Trên màn hình: Một bãi săn cụ thể hoặc cả server chậm đi (quay chậm, trễ thao tác)

Triệu chứng: Quay chậm, Trễ thao tác · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng mạng (Đội hạ tầng)

Phụ thuộc service bên ngoài External dependencies (auth, billing, platform)

Khi service bên ngoài như đăng nhập qua nền tảng, thanh toán, xác thực danh tính chậm hoặc ngừng, người chơi bị kẹt ở đúng bước đó.

Vì sao: Service xác thực hoặc thanh toán bên ngoài gặp sự cố hoặc chậm → Dẫn đến: Chờ phản hồi ở bước đó → Trên màn hình: Không đăng nhập được, thanh toán thất bại. Người đang chơi thì vẫn bình thường

Triệu chứng: Không vào được·kẹt loading, Nuốt thao tác·rollback · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Phát triển server (Đội phát triển game)

Lỗi matchmaking hoặc phân bổ region Wrong region assignment (matchmaking / GeoDNS)

Nếu bị xếp vào server ở region xa thay vì region gần, dù đường truyền vẫn ổn, riêng người chơi đó luôn có ping cao.

Vì sao: Dữ liệu GeoIP sai, VPN, xếp cả tổ đội theo ping trung bình của các thành viên, quy tắc mở rộng sang region xa khi thiếu người, phân bổ theo vị trí của DNS resolver → Dẫn đến: Kết nối vào server ở region bên kia đại dương dù có region gần hơn → Trên màn hình: Trong game đặt server ở nhiều region, chỉ riêng bạn (hoặc chỉ tổ đội của bạn) luôn có ping cao, bị trễ thao tác, kéo ngược, nuốt skill

Triệu chứng: Trễ thao tác, Kéo ngược, Nuốt thao tác·rollback · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game), Hạ tầng mạng (Đội hạ tầng), Bên ngoài (Bên ngoài)

Chứng chỉ TLS hết hạn hoặc cấu hình sai TLS certificate expiry / misconfiguration

Khi chứng chỉ của server đăng nhập, API hoặc server patch hết hạn hoặc thiếu chứng chỉ trung gian, kết nối TLS của các client kết nối mới sẽ thất bại kể từ thời điểm đó.

Vì sao: Chứng chỉ đã quá hạn hiệu lực, server gửi thiếu chứng chỉ trung gian, hoặc ngày giờ trên thiết bị của người chơi bị sai → Dẫn đến: Client xác minh chứng chỉ thất bại và cắt kết nối TLS → Trên màn hình: Không vào được, kẹt loading ở bước đăng nhập hoặc patch, chỉ các tính năng HTTPS như cửa hàng bị lỗi. Người đã vào game từ trước thường vẫn bình thường

Triệu chứng: Không vào được·kẹt loading, Nuốt thao tác·rollback · Phụ trách chính Hạ tầng mạng (Đội hạ tầng) · Phối hợp Hạ tầng server (Đội hạ tầng), Phát triển client (Đội phát triển game)

Giới hạn hàng chờ đăng nhập, thiếu thời gian giữ chỗ khi kết nối lại Login queue cap / no reconnect grace

Ngay sau khi ra mắt hoặc bảo trì, lượng kết nối dồn đến khiến hàng chờ đăng nhập chạm giới hạn và từ chối lượt chờ mới, còn người chơi đang chờ chỉ cần mất kết nối trong giây lát là mất chỗ và phải quay về cuối hàng.

Vì sao: Số người muốn vào nhiều hơn lượng server đăng nhập nhận được cùng lúc nên phải có hàng chờ, và khi hàng chờ quá dài thì server từ chối lượt chờ mới để tự bảo vệ → Dẫn đến: Hàng chờ càng dài thì thời gian chờ càng lâu, và trong lúc đó chỉ cần Wi-Fi hoặc mạng di động rớt trong giây lát là mất chỗ trong hàng → Trên màn hình: Không vào được, kẹt loading, game thoát kèm thông báo lỗi khi đang chờ, lại phải chờ từ cuối hàng

Triệu chứng: Không vào được·kẹt loading, Mất kết nối · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game), Hạ tầng server (Đội hạ tầng)

T1Công cụ

Công cụ chẩn đoán

Khi nhận được báo cáo lag, bạn chỉ cần chọn ba điều: “ai, khi nào, biểu hiện ra sao”. Công cụ sẽ hiện các nguyên nhân trong sách trắng này khớp nhất, xếp theo điểm. Đây chưa phải chẩn đoán chắc chắn, nhưng đủ để quyết định nên hỏi đội nào trước.

T2Công cụ

Chẩn đoán từ dữ liệu quan sát

Khi có báo cáo hoặc cảnh báo, hãy thu hẹp theo thứ tự Phạm vi → Thời điểm → Tầng. Bất thường dồn vào đâu là yếu tố phân định bên phụ trách rõ nhất; bất thường trùng với sự kiện nào giúp thu hẹp nguyên nhân; còn chỉ số ở tầng nào bất thường giúp xác nhận. Dùng kèm phần “Trên đồ thị” và “Cách xác nhận” có trên mỗi thẻ nguyên nhân, bạn có thể chọn ứng viên theo dạng đồ thị và tìm ngay chỗ cần kiểm tra.

Quy trình chẩn đoán

1 Phạm vi

Sự bất thường dồn vào đâu

  • Một quốc gia hoặc nhà mạng (ASN) → Đội hạ tầngMạng Bên ngoàiNhà mạng
  • Một server, kênh hoặc zone → nếu chỉ số host bình thường thì Đội phát triển gameServer, bất thường thì Đội hạ tầngThiết bị server·OS
  • Một OS, thiết bị hoặc bản build → Đội phát triển gameClient
  • Một người, một nhà → Bên ngoàiMôi trường người chơi (nếu nhiều người có cùng biểu hiện thì Đội phát triển gameClient)
  • Tất cả cùng lúc → tài nguyên dùng chung (DB, bộ cân bằng tải, gateway) hoặc bản vừa triển khai
2 Thời điểm

Trùng với việc gì

3 Tầng

Chỉ số ở tầng nào bất thường

  1. Mạng: RTT, mất gói, tỷ lệ truyền lại, lỗi và gói bị hủy trên interface
  2. Host: CPU theo từng core, CPU steal, softirq, gói bị NIC hủy, áp lực bộ nhớ
  3. Server game: thời gian tick, hàng đợi nhận của socket (Recv-Q), CPU theo từng thread, log GC
  4. DB: độ trễ query, chờ khóa, replication lag
  5. Client: frame time, net graph, báo cáo crash

Bảng tín hiệu chẩn đoán

Cần xem gìNếu thấy thế nàyGọi ai trước
Hàng đợi nhận của socket server (Recv-Q)Dồn lại vì tiến trình server không đọc kịpĐội phát triển gameServer (tick dừng, GC, lock)
Truyền lại và RTT theo từng kết nốiChỉ một số kết nối, dồn vào một số ASNĐội hạ tầngMạng Bên ngoàiNhà mạng·đường truyền người chơi
Mọi kết nối trên một hostĐội hạ tầngThiết bị server·OS (NIC, kernel)
Truyền lại và băng thông toàn server tăng ngay sau bản cập nhậtKích thước hoặc tần suất gói thay đổiĐội phát triển gameServer Đội hạ tầngMạng (MTU, giới hạn)
CPU steal, throttling, softirq, gói bị NIC hủyTăngĐội hạ tầngThiết bị server·OS
Chỉ một thread lên 100%, độ trễ run queue, GC pauseTăngĐội phát triển gameServer
Độ trễ DB tăng, số query không đổiIOPS, khóa, tác vụ khácĐội hạ tầngThiết bị DB
Số lượng hoặc dạng query DB thay đổi sau bản cập nhậtN+1, query mớiĐội phát triển gameServer
Giám sát giả lập (RTT, mất gói) từ các điểm đo ở nước ngoàiKémĐội hạ tầngMạng Bên ngoàiNhà mạng
Giám sát giả lập bình thường nhưng chỉ người chơi thấy tệMôi trường người chơi hoặc clientBên ngoàiMôi trường người chơi Đội phát triển gameClient
Phân bố lý do mất kết nốiHeartbeat timeout↑ / RST↑ / server chủ động ngắt↑NAT hoặc tuyến đường / thiết bị / server
Chu kỳ chính xác (đúng giờ, cứ N phút)Tác vụ định kỳ, sao lưu, GC, sự kiệnBên đặt ra lịch đó

Tra theo dạng đồ thị

Chỉ cần biết đồ thị giám sát có dạng gì là số ứng viên đã giảm đi nhiều. Với mỗi dạng trong 13 dạng dưới đây, chúng tôi gom các nguyên nhân tạo ra dạng đó. Hình nhỏ trên thẻ nguyên nhân cũng dùng cùng các dạng này. Đường liền là chỉ số chính cần xem, đường nét đứt là chỉ số xem kèm (số người, thời gian chờ, lỗi, v.v.), đường nét đứt nhạt là mức bình thường.

Vọt lên theo chu kỳ

Bình thường ở mức thấp, rồi vọt lên đều đặn theo cùng một khoảng như vài giây, vài phút hay đúng mỗi đầu giờ.

Thu gom rác (GC) phía client, Kiểm tra của module bảo mật game (anti-cheat), Wi-Fi quét nền, Tác vụ theo lịch, Timer kích hoạt dồn cùng lúc, GC dừng toàn bộ server, GC pause của script engine, fsync dồn dập, Tác vụ sao lưu, nén, quét, Checkpoint, flush log, Tác vụ batch khối lượng lớn, Cache stampede

Thỉnh thoảng vọt lên bất chợt

Vọt lên thất thường, không theo khoảng nào, rồi nhanh chóng trở lại.

Frame time vọt lên, Ngoại suy quá mức (dead reckoning), Dự đoán phía client sai lệch, Fixed timestep chạy bù mất kiểm soát, Tiến trình chạy nền chiếm giữ CPU, Thiếu bộ nhớ và swap phía client, Tiết kiệm điện NIC và lỗi driver, Nhiễu và sóng Wi-Fi yếu, Chuyển qua lại 5G↔LTE liên tục (vùng rìa phủ sóng 5G), Chất lượng đường truyền kém, Ring buffer không đủ, Overhead ảo hóa và noisy neighbor, Bộ đệm socket của kernel quá nhỏ, CPU steal (máy ảo), Dừng do thu hồi bộ nhớ và compaction, Đồng hồ hệ thống nhảy (NTP step), Gửi bị chặn (blocking send) do client chậm, Cấu hình truyền lại của UDP tin cậy, Mất dữ liệu cuối do đóng cưỡng bức bằng RST, Gọi đồng bộ (blocking) trên game thread, Ghi log đồng bộ, Lazy loading phía server, Deadlock trong DB, Lệnh Redis chậm, Quá tải log và giám sát, Lockstep phải chờ người chơi chậm nhất, Rollback netcode dự đoán sai, Phát ngay khi nhận, không có timestamp, Server kiểm tra quá chặt, Tính toán đường đi không khớp khi đồng bộ lệnh, Thứ tự đăng ký tầm nhìn bị rối, Mất snapshot gốc (baseline), Mất thông báo rời đi (đối tượng ma), Nhầm lẫn do dùng lại ID đối tượng, Truyền lại không cần thiết do độ trễ tăng vọt

Tăng như bậc thang từ một thời điểm

Tăng lên một bậc kể từ một thời điểm cụ thể như bản cập nhật, thay đổi cấu hình hay thay đổi tuyến đường, rồi giữ nguyên ở mức đó.

Sự cố cáp quang biển, đường truyền quốc tế, Thay đổi tuyến BGP và hội tụ, Đi qua hệ thống chống DDoS, chặn nhầm, Hiệu năng thay đổi sau khi cập nhật OS, kernel, driver hoặc firmware, Bản cập nhật làm thay đổi mô hình lưu lượng, Query không có index, Query chậm do kế hoạch thực thi thay đổi, Khóa do thay đổi schema (DDL) khi đang vận hành, Phụ thuộc service bên ngoài, Đổi tuyến đường hoặc tuyến ECMP lỗi

Tăng theo số người và tải

Khi số người chơi đồng thời hoặc số người tụ ở một chỗ tăng lên, chỉ số tăng theo còn dốc hơn.

Tải render khi đông người, Nghẽn xử lý gói tin trên main thread, Tràn bộ đệm nhận, Ứng dụng khác trên cùng thiết bị chiếm giữ băng thông, Bufferbloat (hàng đợi của router), Microburst ở switch, Quá nhiều thread và context switch, CPU throttling trong container (CFS quota), Phân mảnh IP của gói UDP, Kiến trúc I/O blocking, Vượt tick budget, Tính toán tầm nhìn (AOI) bùng nổ (N²), Broadcast bùng nổ, Quá tải khu vực chạy trên một thread (hotspot), Tranh chấp lock, Tìm đường (pathfinding) dồn dập, Chi phí serialize và nén, Giao tranh dồn vào một mục tiêu (world boss), Cấp phát bộ nhớ dồn dập, Tranh chấp khóa trên hot row, Replication lag, Đi qua gateway hoặc proxy, Chuyển zone (chuyển giao giữa các server), Ngân sách gửi và mức ưu tiên theo kết nối, Burst gửi làm tràn bộ đệm nhỏ, Không khớp chế độ duplex

Chạm giới hạn rồi đi ngang

Thông lượng hoặc số kết nối chạm một giá trị rồi không tăng thêm được, từ đó thời gian chờ và lỗi bắt đầu tăng.

Thiếu bộ nhớ đồ họa (VRAM), Router yếu hoặc quá nhiệt, Nhà mạng giới hạn tốc độ và quản lý lưu lượng, Đường truyền dùng chung bị DDoS làm bão hòa, Bảng phiên của tường lửa bị đầy, Giới hạn kết nối và cổng của NAT gateway trên cloud, Đường truyền trung tâm dữ liệu bị bão hòa, Ngắt NIC dồn vào một core, Vượt giới hạn PPS trên cloud, Băng thông NIC bị bão hòa, Giới hạn file descriptor, Bảng conntrack của server bị đầy, Cạn cổng tạm (ephemeral port) ở kết nối giữa các server, Hàng đợi message bị dồn ứ, Cạn thread pool, GC thrashing (heap còn ít chỗ trống), Cạn burst credit của ổ đĩa cloud, Chạm giới hạn IOPS, hàng đợi bão hòa, Cạn connection pool, Sự cố dây chuyền, Giới hạn hàng chờ đăng nhập, thiếu thời gian giữ chỗ khi kết nối lại, Streaming thất bại do thiếu bộ nhớ hoặc VRAM, Policer bỏ phần vượt mức, Host server nhận bỏ gói tin, Tường lửa và theo dõi kết nối bỏ gói, Thiết bị trung gian vượt giới hạn xử lý (tường lửa, IPS, chống DDoS)

Luôn cao ngay từ đầu

Luôn nằm ở mức cao, không vọt lên từng đợt. Đây là trường hợp do cấu trúc như khoảng cách, tuyến đường hay thiết kế.

Bộ đệm nội suy không có hoặc quá ngắn, V-Sync và hàng đợi render, Độ phân giải timer, Độ trễ của màn hình, thiết bị nhập và tạo khung hình, Độ trễ lan truyền (khoảng cách vật lý), Định tuyến đi đường vòng, Gộp ngắt quá mức, Độ trễ chờ gộp gói GRO/LRO, Độ trễ vọt lên do quản lý nguồn điện của server (C-state, điều chỉnh xung nhịp), Thuật toán Nagle + delayed ACK, Cache miss, Độ trễ seek của HDD, Chỉ hiển thị sau khi server phản hồi (mô hình yêu cầu-phản hồi), Giao thức nhiều lượt khứ hồi tuần tự (chatty), Không có buffer input cho skill, Client có thẩm quyền, Chờ tick hai lần, Tần suất gửi snapshot thấp, Truyền lại nhanh không cần thiết do gói đến sai thứ tự, Cấu hình RTO không hợp với môi trường, Thiết bị trung gian xóa tùy chọn TCP

Chỉ một phần cao

Phần lớn bình thường, riêng một số người chơi, khu vực, nhà mạng hay thiết bị cao hẳn.

Ổ lưu trữ chậm khiến streaming asset không theo kịp, Client bị crash, Phần mềm bảo mật kiểm tra gói tin, Phần mềm overlay can thiệp vào game, Trễ chuyển trạng thái RRC (chế độ tiết kiệm điện của mạng di động), Sóng di động yếu hoặc vùng lõm sóng, Giới hạn của Wi-Fi công cộng và mạng công ty, Internet vệ tinh (quỹ đạo thấp, địa tĩnh), Một đường ECMP bị lỗi, Hạn chế UDP và kiểm tra gói tin ở cấp quốc gia hoặc nhà mạng, DNS lỗi hoặc chậm, Đi qua VPN hoặc phần mềm tăng tốc game, Bộ cân bằng tải phân bổ lệch, health check đánh giá sai, Cáp hỏng và lỗi cổng, MTU không khớp (chỉ mất gói lớn), Chính sách xử lý client chậm (slow consumer), Keepalive mặc định 2 giờ, Slow start sau thời gian nhàn rỗi, SO_REUSEPORT phân phối bị lệch, Truy cập bộ nhớ NUMA từ xa, Quá nhiều macro và bot, Lỗi matchmaking hoặc phân bổ region, Khung phán định ngắn bị ping ăn mất, Phán định không có bù trễ, Bù trễ quá mức, Cấu trúc host (chủ phòng), Server từ chối sau khi đã hiển thị trước, Người chơi chậm di chuyển dồn cục trên màn hình người khác, Tua nhanh do server xử lý ngay khi gói tới, Kích thước bộ đệm input theo người chơi, Một đồng đội chậm và cơ chế boss, Quyền điều khiển quái nằm ở client chậm, Dữ liệu của một nhân vật quá lớn, Khác kênh, instance hoặc phasing, Bỏ thông báo xuất hiện tới trong lúc loading, Xung đột cổng UDP cố định, Lỗi phân biệt phiên theo IP hoặc thiết bị, Giới hạn chạy nhiều client, Xung đột khi cùng truy cập file cache hoặc asset, Khác tùy chọn hiển thị, Phiên bản hoặc dữ liệu client không khớp, Đối tượng bị giữ lại do ước tính đồng hồ sai, Mất gói ở chặng không dây, Lỗi vật lý (cáp, module quang, đầu nối hỏng), MTU black hole (chỉ gói lớn liên tục bị mất), ACK đến muộn hoặc bị mất (chiều tải lên bị bão hòa)

Đứt quãng rồi dồn về

Lượng nhận được về 0 trong một lúc rồi ào về cùng lúc.

Giới hạn xử lý khi cửa sổ bị thu nhỏ hoặc mất focus, Handover trạm phát sóng (khi đang di chuyển), Bảo trì host cloud và live migration, Lỗi driver hoặc firmware NIC, TCP HOL blocking, TCP RTO và exponential backoff, Giới hạn xử lý ở cửa sổ chạy nền, Thin stream phục hồi chậm, Zero window (khoảng dừng dễ nhầm là truyền lại)

Rớt kết nối hàng loạt

Số kết nối tụt thẳng xuống hoặc số lần mất kết nối vọt lên trong chớp mắt.

Ứng dụng di động chuyển xuống chạy nền, Chuyển đổi Wi-Fi ↔ LTE hoặc 5G, Ánh xạ NAT hết hạn, IP dùng chung của nhà mạng (CGNAT), Idle timeout của bộ cân bằng tải, Hết hạn theo dõi kết nối của security group trên cloud, Failover thiết bị mạng, OOM killer, Lỗi WSAECONNRESET trên socket UDP của Windows, Deadlock, Server crash, Vòng lặp vô hạn và logic chạy mất kiểm soát, Ghi core dump, Failover DB, Mất tiến độ do chu kỳ lưu dài, Sự cố server phụ trợ, Triển khai và khởi động lại, Chứng chỉ TLS hết hạn hoặc cấu hình sai, Ánh xạ NAT hoặc bộ cân bằng tải hết hạn giữa chừng kết nối

Tăng vọt ngay sau đăng nhập hoặc bảo trì

Vọt lên mạnh ngay sau khi mở server hoặc sự kiện bắt đầu, rồi lắng xuống dần.

Tải đồng bộ trên main thread và biên dịch shader, Tràn hàng đợi kết nối (backlog), Spawn dồn dập khi vào khu vực đông người, Cache lạnh (ngay sau khởi động lại), Đăng nhập ồ ạt và query N+1, Autoscaling chậm, Mất thông tin xuất hiện dồn tới ngay sau khi vào, Truyền lại yêu cầu kết nối (SYN)

Không cần code game thì kiểm tra được đến đâu

Chúng tôi đếm cách kiểm tra dễ nhất cho từng nguyên nhân. Công cụ hạ tầng nghĩa là kiểm tra được bằng công cụ của OS, mạng, cloud, DB và tùy chọn khởi động của runtime (log GC, v.v.), không cần sửa code game. Log, chỉ số game là những thứ chỉ thấy được khi game ghi lại, như thời gian tick hay lý do mất kết nối. Tầng nào có nhiều ô “Log, chỉ số game” thì càng có cơ sở để đề nghị đội phát triển bổ sung đo đạc (instrumentation).

Cách đọc con số

Trung bình che mất các lần vọt lên. Với server 20 tick mỗi giây, chỉ cần 1% số tick bị chậm là cứ khoảng 5 giây mọi người lại khựng một lần, nhưng thời gian tick trung bình gần như không đổi. Vì vậy hãy xem thêm phân vị. p50 (trung vị) là giá trị mà một nửa số mẫu nhanh hơn, p99 là giá trị gần với 1 lần chậm nhất trong 100 lần. Thứ người chơi nhớ là “lag” thường nằm ở phía p99.

Khoảng gộp dữ liệu cũng che mất các lần vọt lên. Trên đồ thị trung bình 1 phút, một lần đứng hình 1 giây bị pha loãng còn 1/60. Khi đi tìm các lần đứng hình, hãy xem kèm giá trị lớn nhất hoặc p99 của cùng đồ thị, hoặc một khoảng gộp ngắn hơn.

Jitter là mức dao động của khoảng cách giữa các lần gói tin đến. Dù ping trung bình thấp, jitter lớn vẫn làm bộ đệm nội suy cạn, gây giật khựng và dịch chuyển tức thời.

Cách đoĐo cái gìĐiểm cần lưu ý
ping (ICMP)Thời gian khứ hồi đến thiết bịRouter và server có thể xử lý phản hồi ICMP chậm hoặc giới hạn số lượng, nên kết quả có thể khác với gói tin game. Nếu ICMP bị chặn thì không có phản hồi nào
mtr·tracerouteĐộ trễ và mất gói theo từng hopNếu chỉ một thiết bị ở giữa có tỷ lệ mất gói cao mà các hop sau vẫn bình thường, nhiều khả năng thiết bị đó chỉ giảm phản hồi ICMP. Chỉ mất gói kéo dài đến tận hop cuối mới là mất gói thật
TCP RTT (rtt trong ss -ti)Thời gian khứ hồi do kernel đo cho từng kết nốiĐáng tin nhất vì là giá trị của chính kết nối game. Xem được theo từng người chơi ở phía server
Ping trong gameThời gian khứ hồi do game tự đo bằng message riêngNếu đo bên trong vòng lặp game thì lẫn cả thời gian chờ khung hình và tick. Dù đường truyền bình thường, server hay PC bận là con số tăng

Việc làm được ngay, việc cần bổ sung vào code game

Không cần code game
  • Gắn thêm chiều dữ liệu: gắn quốc gia và nhà mạng (ASN) vào IP client trong log kết nối và log bộ cân bằng tải, để thấy được “chỉ ở nước ngoài”, “chỉ một nhà mạng”.
  • Chất lượng kết nối: trên server, thu thập RTT và truyền lại theo từng kết nối bằng ss -ti hoặc công cụ eBPF rồi xem theo ASN.
  • Nhìn vào bên trong server từ bên ngoài: hàng đợi socket, CPU theo từng thread (pidstat -t), độ trễ run queue, log GC bật được chỉ bằng tùy chọn khởi động.
  • Đo tuyến đường: giám sát giả lập từ phía quốc gia và nhà mạng cần xét (RIPE Atlas, server đo đặt ở các region cloud) và mtr.
  • Nhật ký thay đổi: đánh dấu triển khai, bản cập nhật, thay đổi cấu hình, công việc mạng bằng đường dọc trên mọi đồ thị. Đây là điểm xuất phát để kết luận “sau bản cập nhật”.
Thêm tối thiểu vào code game
  • Báo cáo tóm tắt từ client: cứ 30–60 giây gửi RTT p50 và p95, jitter, mất gói, FPS, số lần frame time vọt lên, bản build, server và kênh.
  • Chỉ số tick của server: thời gian tick p50 và p99, số lần vượt tick budget, số người theo từng zone, hàng đợi gửi theo từng kết nối.
  • Mã lý do mất kết nối: heartbeat timeout, RST, server chủ động ngắt, xác thực thất bại, bảo trì, dùng cùng một bộ mã ở cả hai phía.
  • ID phiên và thời điểm: mọi log đều có ID phiên, nhân vật, server và giờ UTC đã đồng bộ.
  • Nút báo lag: gửi lên RTT, FPS và khoảng trống tick của 60 giây gần nhất kèm ID phiên.
T3Công cụ

Sự cố thực tế và quy trình

Tập hợp trình tự kiểm tra cho hai tình huống thường gặp, cùng các sự cố thực tế do chính nhà phát triển gốc và đơn vị vận hành công bố. Mỗi bước và mỗi sự cố đều dẫn tới các thẻ nguyên nhân liên quan.

Quy trình theo tình huống

Lag sau bản cập nhật

Khi báo cáo lag tăng lên kể từ một bản cập nhật hoặc một lần triển khai cụ thể. Dùng khi các báo cáo kiểu “từ bản cập nhật này game có gì đó không ổn” dồn về, hoặc khi đồ thị tăng như bậc thang từ một thời điểm rồi giữ nguyên ở mức đó.

  1. Xác định thời điểm bắt đầu và gom mọi thay đổi quanh thời điểm đó: Tìm thời điểm báo cáo bắt đầu dồn về và thời điểm đồ thị tăng lên như bậc thang, rồi ghi lại đầy đủ mọi thay đổi được đưa ra trước và sau thời điểm đó. Xem cùng lúc bản cập nhật client, triển khai server, thay đổi cấu hình, thay đổi schema DB (DDL) và khởi động lại, công việc về mạng và tường lửa, thay thế hạ tầng (loại instance, kernel, driver). Nếu mỗi lần triển khai đều dùng tính năng chú thích (annotation) của công cụ giám sát để đánh một vạch dọc trên mọi đồ thị, bước này sẽ xong rất nhanh. Nếu bản cập nhật game và công việc hạ tầng được đưa ra trong cùng một đợt bảo trì, giữ cả hai trong danh sách nghi vấn. Gọi ai trước: cả đội phát triển game và đội hạ tầng, tức các bên đã đưa ra thay đổi.
  2. Chia theo phạm vi: build, thiết bị, server, khu vực: Xem bất thường tập trung ở chiều nào. Nếu chỉ người chơi dùng bản build mới có vấn đề, nghi ngờ client trước; nếu chỉ một số OS, card đồ họa hoặc thiết bị có vấn đề, nghi ngờ hiệu năng client hoặc driver; nếu chỉ một số server, kênh hoặc zone, nghi ngờ server; nếu chỉ một số quốc gia hoặc nhà mạng, nghi ngờ tuyến đường mạng; nếu tất cả cùng có vấn đề một lúc, nghi ngờ tài nguyên dùng chung (DB, bộ cân bằng tải, gateway) hoặc bản triển khai server vừa đưa ra. Nếu telemetry của client có số hiệu build, hãy đặt ping, FPS, số lần frame spike và số lần mất kết nối của build cũ và build mới cạnh nhau. Nếu ping không đổi mà chỉ FPS kém đi thì vấn đề nghiêng về hiệu năng client hơn là mạng. Gọi ai trước: dồn vào build hoặc thiết bị thì gọi đội phát triển game (client); dồn vào server hoặc kênh thì gọi đội phát triển game (server) nếu chỉ số host bình thường, đội hạ tầng (thiết bị server·OS) nếu bất thường; dồn vào quốc gia hoặc nhà mạng thì gọi đội hạ tầng (mạng).
  3. So sánh phiên bản mới và phiên bản cũ trong cùng khung giờ: Nếu chỉ so sánh trước và sau khi triển khai, các biến động theo ngày trong tuần, khung giờ và sự kiện sẽ lẫn vào, khiến khó kết luận. Nếu được, hãy đưa phiên bản mới lên một số server trước (canary), rồi so sánh song song với các server phiên bản cũ trong cùng khung giờ (nhóm đối chứng) về thời gian tick p50 và p99, số lần vượt tick budget, CPU, bộ nhớ và tỷ lệ lỗi. Nếu đã triển khai toàn bộ, hãy so sánh với cùng ngày, cùng khung giờ của tuần trước. Nếu chỉ nhìn trung bình của toàn bộ server, vấn đề ở một số server hoặc zone sẽ bị che lấp, nên hãy tách ra xem theo từng server và từng zone. Gọi ai trước: đội phát triển game (server).
  4. So sánh đặc trưng lưu lượng trước và sau: Dù không biết code server, vẫn có thể dùng các giá trị nhìn thấy từ phía mạng để kiểm tra xem bản cập nhật có làm thay đổi hình dạng lưu lượng hay không. So sánh trước và sau: số gói tin mỗi giây (pps) và số byte trên mỗi người chơi, kích thước gói trung bình và tối đa, số kết nối, kích thước burst gửi dồn một lượt ở mỗi tick. Nếu gói UDP bắt đầu vượt MTU của tuyến đường (thường là 1.500 byte), sẽ xảy ra phân mảnh IP. Chỉ cần mất một fragment là mất cả gói, và có những NAT hoặc tường lửa bỏ hẳn fragment. Người chơi đi qua đoạn có MTU nhỏ ở giữa đường (tunnel, VPN) sẽ chỉ bị mất các gói lớn. Nếu pps tăng, hãy xem đã chạm giới hạn PPS của instance cloud hay giới hạn xử lý của tường lửa, thiết bị chống DDoS chưa. Gọi ai trước: nếu đặc trưng lưu lượng thay đổi, gửi kèm bằng chứng cho đội phát triển game (server); nếu đặc trưng giữ nguyên mà chỉ mất gói và truyền lại tăng, gọi đội hạ tầng (mạng).
  5. So sánh loại và số lần chạy query DB trước và sau: Nếu độ trễ DB tăng, trước tiên xem số query (QPS) có tăng theo không. pg_stat_statements của PostgreSQL hay bảng tổng hợp theo digest của MySQL Performance Schema gom các query chỉ khác nhau về giá trị thành một loại và cộng dồn số lần chạy cùng tổng thời gian. Vì vậy, so sánh danh sách query hàng đầu trước và sau bản cập nhật sẽ làm lộ ra các query mới xuất hiện, các query có số lần chạy tăng gấp nhiều lần (N+1) và các query đọc toàn bộ bảng mà không dùng index (với MySQL là cột SUM_NO_INDEX_USED). Gọi ai trước: nếu QPS hoặc dạng query thay đổi thì gọi đội phát triển game (server); nếu query giữ nguyên mà chỉ độ trễ tăng thì gọi đội hạ tầng (DB: kế hoạch thực thi, IOPS, khóa).
  6. Dùng chỉ số của host và tiến trình server để phân định tầng: Không cần code, dùng các giá trị nhìn thấy từ OS để phân định vấn đề nằm bên trong server hay ở host. Nếu hàng đợi nhận (Recv-Q) của socket server dồn lên, tiến trình server đang không đọc kịp (tick bị dừng, GC, lock); nếu chỉ một thread chạy 100%, đó là điểm nghẽn ở một thread duy nhất; nếu thời gian dừng trong log GC tăng, cách dùng bộ nhớ đã thay đổi. Kiểm tra thêm xem có phải bản triển khai đã để log level cao khiến lượng ghi log tăng lên không. Ngược lại, nếu CPU steal, throttling hoặc số gói bị NIC bỏ (drop) tăng, hãy xem phần hạ tầng đã thay đổi cùng thời điểm (loại instance, kernel, giới hạn container). Gọi ai trước: tín hiệu bên trong tiến trình thì gọi đội phát triển game (server), tín hiệu ở host thì gọi đội hạ tầng (thiết bị server·OS).
  7. Hoàn tác để xác nhận và ghi lại kết quả: Hoàn tác thay đổi đáng nghi nhất chỉ trên một số server hoặc một nhóm người chơi (rollback, tắt feature flag), hoặc đưa cấu hình về giá trị cũ, rồi xem triệu chứng có biến mất theo không. Nếu chỉ phía đã hoàn tác được cải thiện thì nguyên nhân được xác nhận. Bản thân việc hoàn tác cũng có thể gây chậm trong chốc lát do khởi động lại và cache lạnh, nên nếu không gấp, hãy làm vào khung giờ vắng người. Ghi kết quả vào hồ sơ sự cố kèm ID nguyên nhân, và đưa các ngưỡng về kích thước gói, số query và thời gian tick vào danh mục kiểm tra trước khi triển khai bản cập nhật tiếp theo. Gọi ai trước: đội đã đưa ra thay đổi.

Mở thêm quốc gia hoặc khu vực ở nước ngoài

Khi mở dịch vụ ở một quốc gia mới hoặc thêm region, trung tâm dữ liệu mới. Dùng cho cả việc kiểm tra trước khi ra mắt và việc phân định các báo cáo kiểu “trong nước thì ổn, chỉ người chơi ở quốc gia mới bị lag”.

  1. Đo chất lượng tuyến đường của từng nhà mạng địa phương trước khi ra mắt: Với từng nhà mạng chính (ASN) của quốc gia mục tiêu, đo phân bố thời gian khứ hồi (RTT), jitter (độ dao động của khoảng cách giữa các lần gói tin đến) và tỷ lệ mất gói đến các vị trí ứng viên đặt server game. Một con số trung bình duy nhất sẽ che mất khác biệt giữa các nhà mạng, nên hãy xem trung vị và phân vị 95 của từng nhà mạng, tách riêng giờ cao điểm buổi tối và rạng sáng. Mạng đo lường công khai RIPE Atlas cho phép chọn quốc gia hoặc ASN rồi gửi ping, traceroute từ các probe trên toàn thế giới; cũng có thể dựng VM tạm thời ở region ứng viên để đo. Thiết bị trung gian đôi khi giới hạn tốc độ phản hồi ICMP, nên nếu được, hãy đo thêm bằng đúng giao thức và cổng mà game dùng. Nếu riêng một nhà mạng đi qua thành phố xa bất thường, đó là vấn đề peering hoặc tuyến đường. Nhà mạng ưu tiên chi phí hơn độ trễ khi chọn tuyến, nên cả điểm đến ở gần cũng có thể bị đi vòng xa. Gọi ai trước: đội hạ tầng (mạng); nếu tuyến đường nằm ở phía nhà mạng thì gọi bên ngoài (nhà mạng, IX).
  2. So sánh số đo với giới hạn mà thiết kế game chịu được: So sánh RTT và jitter đo được với khung phán định của game (thời gian phản ứng cho các thao tác như né, đỡ đòn), giới hạn bù trễ, độ dài bộ đệm nội suy và kích thước bộ đệm input. Ví dụ, nếu khung phán định đỡ đòn là 0,2 giây, thì với người dùng của những nhà mạng mà độ trễ khứ hồi cộng với bộ đệm nội suy vượt quá mức đó, dù phản ứng đúng lúc vẫn bị tính là trễ. Nếu nới rộng bù trễ để bù lại, lần này phía bị đánh trúng sẽ báo cáo nhiều hơn rằng “đã núp sau tường rồi mà vẫn trúng đòn”. Nếu có nhiều nhà mạng vượt giới hạn, đội hạ tầng xem xét phương án đặt region hoặc edge PoP gần hơn, còn đội phát triển game xem lại các giá trị phán định, nội suy và bù trễ. Bảng tham chiếu nằm trong chương về cơ chế đồng bộ của sách trắng này. Gọi ai trước: đội phát triển game (server và client: giới hạn thiết kế), đội hạ tầng (mạng: vị trí region và PoP).
  3. Kiểm tra MTU và UDP có đi qua được không: Kiểm tra xem gói tin lớn nhất của game có đi qua mạng địa phương nguyên vẹn không. Gửi ping có cờ cấm phân mảnh (DF) với nhiều kích thước khác nhau để đo MTU của tuyến đường, và xem có đoạn nào nhỏ hơn 1.500 byte như PPPoE, tunnel hay mạng di động không. Tiêu chuẩn cho truyền datagram như UDP (RFC 8899) khuyến nghị 1.200 byte làm kích thước cơ bản đi qua được hầu hết các tuyến trên IPv4, nên nếu gói lớn nhất của game vượt mức này, hãy thống nhất với đội phát triển game phương án thu nhỏ hoặc chia nhỏ gói. Kiểm tra thêm xem Wi-Fi công cộng, mạng công ty hoặc một số nhà mạng có chặn hay giới hạn tốc độ UDP hoặc cổng của game không, và xem đã có đường thay thế (TCP, cổng 443) để dùng khi bị chặn chưa. Gọi ai trước: đội hạ tầng (mạng) và đội phát triển game (server: kích thước gói).
  4. Đo idle timeout của NAT và CGNAT, rồi chỉnh khoảng cách heartbeat cho phù hợp: Đo xem router gia đình và mạng di động (CGNAT) ở địa phương xóa ánh xạ (mapping) của kết nối UDP nhàn rỗi sau bao lâu. Trong mỗi lần thử, cho thiết bị thử nghiệm gửi một gói tới server để tạo ánh xạ, sau đó thiết bị không gửi gì nữa, còn server gửi một gói về thiết bị sau một khoảng thời gian định sẵn (30 giây, 60 giây, 120 giây …). Khoảng thời gian mà từ đó thiết bị bắt đầu không nhận được gói chính là idle timeout của mạng đó. Tiêu chuẩn (RFC 4787) quy định ánh xạ UDP không được hết hạn trước 2 phút và khuyến nghị mặc định từ 5 phút trở lên, nhưng giá trị thực tế khác nhau rất nhiều giữa các thiết bị, có thiết bị xóa sớm hơn. Ánh xạ chỉ chắc chắn được làm mới bằng gói đi ra từ thiết bị, nên heartbeat phải do client gửi; hãy kiểm tra khoảng cách heartbeat có bằng hoặc nhỏ hơn một nửa giá trị ngắn nhất trong số: giá trị đo được, idle timeout của bộ cân bằng tải và của security group trên cloud. Gọi ai trước: đội phát triển game (client: khoảng cách heartbeat; server: giá trị timeout), đội hạ tầng (cấu hình bộ cân bằng tải, security group).
  5. Kiểm tra dịch vụ bên ngoài và thiết bị bảo mật mà lưu lượng từ địa phương đi qua: Kiểm tra xem đăng nhập qua nền tảng địa phương, thanh toán và xác minh danh tính có phản hồi đúng tốc độ không; DNS địa phương có phân giải đúng địa chỉ server đăng nhập và server bản cập nhật không; CDN có phân phối bản cập nhật từ PoP gần quốc gia đó không. Xem dải IP của quốc gia mới có bị dính vào quy tắc chặn theo quốc gia và giới hạn tốc độ của hệ thống chống DDoS, tường lửa không, đặc biệt là dải CGNAT (nơi nhiều thuê bao dùng chung một IP) có bị chặn cả loạt không. Gọi ai trước: đội hạ tầng (thiết bị bảo mật, DNS, CDN), bên ngoài (nền tảng, đơn vị thanh toán, nhà mạng).
  6. Sau khi ra mắt, tách số liệu theo quốc gia và ASN: Gắn quốc gia và ASN vào IP client trong log kết nối và log của bộ cân bằng tải, rồi xem RTT, truyền lại, số lần mất kết nối và lý do mất kết nối (heartbeat timeout, RST, server kick) theo từng quốc gia và nhà mạng. Có thể dùng cơ sở dữ liệu miễn phí như MaxMind GeoLite ASN để chuyển IP thành ASN và tên tổ chức; khi lưu, hãy rút gọn IP về mức /24 hoặc ASN cho phù hợp với quy định về dữ liệu cá nhân của nước sở tại. Nếu chỉ dồn vào một ASN, xem trước tuyến đường của nhà mạng đó (đội hạ tầng, bên ngoài); nếu cả quốc gia mới đều có vấn đề, xem khoảng cách và giới hạn thiết kế (đội hạ tầng, đội phát triển game); nếu chỉ xấu đi vào buổi tối, xem tắc nghẽn peering. Nếu chỉ một số người chơi lúc nào cũng có ping cao, cùng đội phát triển game (server) kiểm tra xem họ có bị xếp vào region xa do GeoIP sai, VPN hoặc do xếp theo vị trí của đội trưởng tổ đội không. Nếu giám sát giả lập vẫn bình thường mà chỉ phía người chơi có vấn đề, vấn đề nằm ở môi trường người chơi hoặc phía client.
  7. Kiểm tra ảnh hưởng của người chơi ở xa lên những người chơi khác: Khi số người chơi kết nối từ xa tăng lên, ảnh hưởng không chỉ dừng lại ở màn hình của chính họ. Input của người chơi có kết nối chậm đến dồn một lượt, khiến trên màn hình người khác, riêng nhân vật đó bị tua nhanh; đồng thời nhân vật bị server bắt lỗi ở bước kiểm tra tốc độ và hồi chiêu, gây kéo ngược hoặc skill bị từ chối. Với các cơ chế (gimmick) đòi hỏi cả tổ đội phối hợp, phản ứng muộn của một người chậm trở thành thất bại của cả tổ đội; còn với cơ chế lockstep, mọi người phải chờ người chậm nhất. Sau khi ra mắt ở quốc gia mới, hãy xem các báo cáo kiểu “chỉ một nhân vật trông bất thường” từ người chơi hiện có có tăng lên không, rồi cùng đội phát triển game quyết định về bộ đệm input, ngưỡng dung sai khi kiểm tra và việc tách khu vực ghép trận. Gọi ai trước: đội phát triển game (server).

Sự cố thực tế

Chỉ chọn các bản phân tích sau sự cố (postmortem) do chính công ty game và công ty hạ tầng công bố. Phần tóm tắt chỉ viết trong phạm vi những gì bài gốc nêu; hãy xem bài gốc để biết diễn biến chi tiết.

CCP Games 2014: EVE Online: server quá tải trong trận hạm đội quy mô lớn tại HED-GP

Trong trận hạm đội quy mô lớn tại hệ sao HED-GP, được phân tích trong bài tổng kết tháng 1 năm 2014, server bị quá tải nặng. Time Dilation (tính năng làm chậm thời gian trong game khi quá tải) đã chạm mức sàn 10% và cả chiến trường chuyển sang quay chậm, nhưng tải vẫn tiếp tục dồn lên. Mức tồn đọng của tác vụ xử lý việc dừng và kích hoạt lặp lại của các module (Dogma Lateness) lên tới tối đa 193 giây thời gian trong game, tức khoảng 32 phút thời gian thực. Trận 6VDT vào tháng 7 năm 2013, với quy mô gần như tương đương, đạt tối đa 42 giây (khoảng 7 phút thực). CCP nói trước rằng họ không thể chắc chắn: công cụ phân tích hiệu năng tự nó cũng làm tăng tải, nên họ không chạy công cụ này trong tình huống như vậy. Sau đó CCP nêu hai nguyên nhân nhiều khả năng nhất. Thứ nhất, trận đánh kéo dài nên phần tải chưa xử lý kịp cứ tiếp tục dồn lại. Thứ hai, drone được dùng nhiều hơn: số drone được triển khai trong trận (không tính trùng) là 21.123 ở 6VDT và 38.852 ở HED-GP, tức nhiều hơn 84%. Việc thông báo hành động của một người cho tất cả những ai nhìn thấy người đó làm lượng dữ liệu gửi đi tăng theo bình phương số người (O(n²)), và mỗi lần tấn công, drone tạo ra nhiều message hơn. Code chọn mục tiêu tấn công của drone cũng thường xuyên duyệt toàn bộ các mục tiêu có thể tấn công trong cùng chiến trường, nên chi phí tăng gần như n².

Khi lượng xử lý ở một khu vực đông người vượt quá giới hạn, cả khu vực đó rơi vào quay chậm, và trận đánh càng kéo dài thì phần xử lý tồn đọng càng nhiều, khiến trễ thao tác càng lớn. Tín hiệu cần kiểm tra là thời gian tick và lượng tác vụ tồn đọng của server (node) phụ trách khu vực đó, cùng với số người và số đối tượng; đặc điểm nhận biết là các khu vực khác vẫn bình thường. Bên phụ trách chính là đội phát triển game (server), và chỗ cần sửa là phạm vi đối tượng nhận thông báo cho mỗi hành động và chi phí tìm mục tiêu của AI. Thiết kế làm chậm thời gian trong game không xóa được tình trạng quá tải, nhưng nó khiến mọi người cùng chậm đi với một tốc độ, nhờ đó tránh được việc chỉ một số hành động bị trễ mãi không dứt. Bài gốc

Riot Games 2015: Lưu lượng League of Legends đi đường vòng xa và Riot Direct

Đây là bài viết kỹ thuật trong đó Riot Games giải thích vì sao Internet không phù hợp với game thời gian thực. Lưu lượng thực tế do một người chơi League of Legends báo cáo lẽ ra phải đi thẳng từ San Francisco đến Portland, nhưng lại đi qua Los Angeles, Denver và Seattle, nên mất 70 ms, trong khi đi thẳng chỉ cần 14 ms. Riot giải thích rằng khi router bị tràn và gói tin bị bỏ, các tướng khác trên màn hình sẽ nhảy lung tung, còn đạn và chiêu bay (projectile) trông như dịch chuyển tức thời. Riot chỉ ra nguyên nhân nằm ở tuyến đường và router. Các nhà cung cấp mạng trục (backbone) và nhà mạng ưu tiên đưa lưu lượng qua tuyến rẻ nhất hơn là tuyến có độ trễ thấp nhất, và khi tuyến đường do BGP chọn đi vòng xa thì số router phải đi qua cũng tăng lên. Router chịu tải xử lý theo số lượng gói tin, bất kể kích thước gói. Gói tin game chỉ khoảng 55 byte, nên với cùng một lượng dữ liệu, số gói gấp 27 lần so với gói 1.500 byte và làm đầy bộ đệm đầu vào của router nhanh hơn tương ứng. Theo Riot, nhiều router khi quá tải sẽ bỏ gói UDP trước tiên. Để giải quyết, Riot xây dựng mạng riêng Riot Direct: đặt router tại 10 điểm trung chuyển Internet lớn ở Mỹ và kết nối trực tiếp (peering) với càng nhiều nhà mạng càng tốt. Theo phần 2 của loạt bài, tỷ lệ người chơi có ping dưới 80 ms tăng từ 31% lên 50% trong hơn 9 tháng, và lên 80% chỉ sau một đêm khi server game được chuyển đến Chicago.

Nếu ngay trong cùng một quốc gia mà chỉ người dùng của một nhà mạng có ping cao bất thường, hãy nghi ngờ tuyến đường. Tín hiệu cần kiểm tra là phân bố RTT theo từng nhà mạng (ASN) và các thành phố trung chuyển hiện ra trong traceroute. Bên phụ trách chính là đội hạ tầng (mạng), khắc phục bằng peering trực tiếp với nhà mạng, kết nối IX và chọn vị trí đặt server. Chính sách định tuyến phía nhà mạng thì cần trao đổi với bên ngoài (nhà mạng). Trường hợp này cũng cho thấy chỉ riêng việc chuyển server về gần trung tâm phân bố người chơi đã mang lại hiệu quả lớn. Bài gốc

Riot Games 2020: League of Legends: host edge của server châu Âu và Brazil bị quá tải

Cuối tháng 2 năm 2020, các server EUW, EUNE và BR của League of Legends gặp sự cố nhiều lần, khiến số trận mới bắt đầu giảm mạnh. Các dịch vụ backend như ghép trận và server game đều báo trạng thái bình thường, nhưng gần như không có lưu lượng đi vào. Riot đã lùi lịch một tuần để không mở chế độ giải đấu (Clash) trên cụm server có thể thiếu ổn định. Bài tổng kết không ghi mỗi sự cố kéo dài bao lâu. Ba yếu tố chồng lên nhau. Thứ nhất, yêu cầu gửi tới một dịch vụ được tạo sai, nên trong một số trường hợp nhất định cứ thất bại rồi lại bị thử lại liên tục, làm số yêu cầu tăng vọt. Thứ hai, một lỗi tương thích đã biết giữa hệ thống container và phiên bản OS khiến bộ nhớ bên trong OS bị rò rỉ; việc nâng cấp mới chỉ hoàn tất trên khoảng 60% toàn bộ môi trường container của Riot, còn các cụm châu Âu và Mỹ Latinh vẫn đang nâng cấp dở. Thứ ba, các container edge (nhận lưu lượng từ Internet, lọc rồi chuyển vào backend) được bố trí tách nhau trong cùng một shard (nhóm server), nhưng giữa các shard khác nhau thì không có ràng buộc như vậy, nên mỗi lần sự cố đều có container edge của ít nhất ba shard dồn trên một host. Lượng thử lại tăng vọt đổ dồn vào host đó, và rò rỉ bộ nhớ làm host đó ngừng hoạt động.

Khi mọi dịch vụ phía sau đều báo “bình thường nhưng không có lưu lượng đi vào”, hãy xem lớp phía trước (edge, gateway, bộ cân bằng tải). Tín hiệu cần kiểm tra là số kết nối inbound dồn lệch vào một số host và tỷ lệ thất bại, thử lại của một loại yêu cầu cụ thể. Bên phụ trách chính là đội phát triển game (server: yêu cầu bị tạo sai và cách thử lại), còn quy tắc bố trí container, nâng cấp OS và cảnh báo phân bố lệch do đội hạ tầng (thiết bị server·OS) đảm nhận. Riot đã sửa code tạo yêu cầu, thay đổi để lượt thử lại không tăng vọt, và đặt cảnh báo phân bố lệch cho đến khi triển khai được việc phân tán giữa các shard. Bài gốc

Riot Games 2021: Sự cố 5 giờ ở League of Legends EUW: một DB phụ làm tê liệt toàn bộ server

Ngày 22 tháng 1 năm 2021, server EUW của League of Legends không hoạt động bình thường trong thời gian nhỉnh hơn 5 giờ. Hai chỉ số là số người chơi đã đăng nhập và số người chơi đang trong trận cùng lúc bị đứt, và giữa hai lần khởi động lại, số lượt đăng nhập tăng nhưng gần như không có trận nào bắt đầu. Server chính của một DB phục vụ tính năng không quan trọng bị hỏng phần cứng, và DB đó không được cấu hình tự động chuyển sang server dự phòng (failover). Mỗi DB có connection pool riêng, nhưng mọi pool đều dùng chung một thread pool; các tác vụ gửi tới DB bị hỏng không kết thúc mà cứ chiếm giữ thread, khiến cả hệ thống không còn thread để dùng. Giữa lúc cảnh báo dồn dập, Riot nghi ngờ trước tiên cuộc tấn công mạng ác ý vừa gặp gần đây và một đợt thao tác phần cứng ở khu vực khác, nên phải khoảng 1 giờ sau mới để ý đến cảnh báo của DB bị hỏng. Do mọi hệ thống chạy trong cùng một JVM, khi GC dừng tiến trình mỗi lần vài giây giữa lúc tải kết nối lại dồn đến sau khi khởi động lại, việc thu thập chỉ số cũng bị gián đoạn một khoảng dài. Hàng chờ đăng nhập cũng không giữ đúng giới hạn đã cấu hình nên lượng người vào lúc nhiều lúc ít.

Ngay cả một DB phụ bị coi là không quan trọng cũng có thể làm ngừng toàn bộ hệ thống thông qua tài nguyên dùng chung như thread pool. Tín hiệu cần kiểm tra là số yêu cầu đang chờ của từng DB, mức sử dụng thread pool, và tỷ lệ số trận bắt đầu quá thấp so với số lượt đăng nhập. Bên phụ trách là đội phát triển game (server: cô lập thread pool, timeout) và đội hạ tầng (DB: failover tự động). Khi cảnh báo dồn dập, người ta dễ nghi ngờ trước tiên những vấn đề vừa gặp gần đây (như tấn công), nên hãy loại trừ lần lượt theo trình tự chẩn đoán (Phạm vi → Thời điểm → Tầng). Sau khi khởi động lại, kiểm tra thêm xem hàng chờ đăng nhập có giới hạn lượng người vào đúng như cấu hình không. Bài gốc

Roblox 2021: Sự cố 73 giờ của Roblox: tranh chấp trong cụm service discovery (Consul)

Chiều ngày 28 tháng 10 năm 2021 (giờ Thái Bình Dương), sự cố bắt đầu từ tải CPU cao trên một server Consul. Lúc 16:35, số người chơi đang kết nối giảm còn một nửa so với bình thường, rồi toàn bộ dịch vụ ngừng hoạt động. Phải đến 16:45 ngày 31 tháng 10, mọi người chơi mới vào lại được, tức mất 73 giờ kể từ khi sự cố bắt đầu. Roblox cho biết mỗi ngày có 50 triệu người sử dụng nền tảng này. Roblox dùng HashiCorp Consul cho service discovery (tính năng để các dịch vụ tìm địa chỉ của nhau), health check và kho KV, và một cụm Consul duy nhất gánh cùng lúc nhiều workload. Có hai nguyên nhân gốc. Thứ nhất, tính năng streaming mới của Consul (đã được mở rộng dần trong nhiều tháng) được bật thêm cho dịch vụ định tuyến lưu lượng vào ngày trước sự cố, đồng thời số node của dịch vụ này tăng 50%. Dưới tải đọc và ghi đều rất lớn, tính năng này gây tranh chấp trên một tài nguyên dùng chung (một Go channel). Trên các server hai socket (NUMA) có nhiều core hơn được thay vào giữa sự cố, tranh chấp còn nặng hơn. Thứ hai, việc quản lý danh sách trang trống (freelist) của BoltDB, nơi Consul lưu log Raft, trở nên chậm bất thường: mỗi lần thêm dữ liệu từ 16 kB trở xuống lại ghi 7,8 MB xuống ổ đĩa. Trung vị độ trễ ghi KV, bình thường dưới 300 ms, lên tới 2 giây, và trên server leader bị chậm còn quan sát thấy zero window (bộ đệm TCP đầy). Vì hệ thống telemetry phụ thuộc vào Consul, các chỉ số cần để tìm nguyên nhân cũng mất theo.

Khi một hệ thống nền tảng mà nhiều dịch vụ cùng phụ thuộc (service discovery, kho cấu hình, xác thực) bị chậm, mọi tính năng ngừng cùng một lúc. Tín hiệu cần kiểm tra là độ trễ ghi, số lần đổi leader và CPU của hệ thống đó, cùng với các thay đổi cấu hình ngay trước sự cố. Bên phụ trách gồm cả đội phát triển game (server) và đội hạ tầng (thiết bị server·OS). Hệ thống giám sát phải được tách riêng, không phụ thuộc vào chính hệ thống nó giám sát, thì khi có sự cố mới vẫn xem được chỉ số. Khi phục hồi, cache đang trống nên nếu nhận người chơi vào cùng lúc thì hệ thống có thể sập lại; vì vậy Roblox dùng DNS để điều chỉnh tỷ lệ người chơi được vào, tăng dần mỗi lần khoảng 10%. Bài gốc

Square Enix 2021: FINAL FANTASY XIV: tình trạng quá đông khi ra mắt bản mở rộng và lỗi hàng chờ đăng nhập

Từ đợt early access của bản mở rộng Endwalker vào tháng 12 năm 2021, các world đều đông nghẹt. Hàng chờ đăng nhập kéo dài, và Error 2002 xuất hiện thường xuyên khi đăng nhập từ màn hình chọn nhân vật hoặc trong lúc đang chờ. Ngoài ra còn có tình trạng một số world và zone bị sập (Error 3001) và hàng chờ bị timeout (Error 4004). Đến thời điểm thông báo ngày 11 tháng 12, tức ngày thứ 8 của early access, tình trạng đông nghẹt vẫn tiếp diễn. Error 2002 xảy ra trong hai trường hợp. Trường hợp thứ nhất là khi số người chờ ở mỗi trung tâm dữ liệu logic vượt 17.000. Đây là giới hạn được đặt ra để hàng chờ không dài đến mức làm sập server đăng nhập, và khi đó client bị thoát hẳn. Ngày 7 tháng 12, Square Enix đưa thiết bị dự phòng dành cho phát triển vào làm server lobby để nâng giới hạn này; lỗi giảm đi nhưng hàng chờ lại càng dài hơn. Trường hợp thứ hai là khi đường truyền của người chơi đang chờ không ổn định. Thời gian chờ càng dài thì càng nhiều lần kết nối bị ngắt trong chốc lát do mất gói trên tuyến Internet hoặc Wi-Fi chập chờn. Server lobby chờ kết nối lại trong khoảng vài chục giây đến 1 phút; nếu kết nối lại trong khoảng đó, người chơi được tiếp tục từ vị trí cũ trong hàng chờ, còn nếu quá thời gian thì phải xếp lại từ cuối. Square Enix cho biết phần lớn báo cáo thuộc trường hợp này. Do thiếu chip bán dẫn, họ cũng không thể tăng số world ngay được.

Hàng chờ càng dài thì những lần đứt kết nối ngắn của người chơi đang chờ càng dễ biến thành lỗi kết nối. Dù cùng một mức quá tải, lỗi lại dồn vào những người dùng Wi-Fi hoặc đường truyền không ổn định, nên đây trở thành vấn đề “chỉ một số người gặp”. Tín hiệu cần kiểm tra là độ dài hàng chờ, thời gian chờ, và tỷ lệ ngắt kết nối trong lúc chờ trong số các lý do ngắt kết nối. Bên phụ trách chính là đội phát triển game (server: giới hạn hàng chờ và thời gian giữ chỗ khi kết nối lại), còn việc tăng thêm server lobby và server world do đội hạ tầng cùng thực hiện. Đặt thời gian giữ chỗ khi kết nối lại đủ dài sẽ giúp những lần đứt kết nối ngắn trên đường truyền của người chơi ít dẫn tới mất lượt chờ hơn. Bài gốc

Cloudflare 2020: Cloudflare: lỗi cấu hình backbone làm mất lưu lượng ở một số thành phố

Nhiều game giao việc phục vụ web, API và chống DDoS cho nhà cung cấp CDN, nên đây là kiểu sự cố hạ tầng mà game cũng bị ảnh hưởng theo. Từ 21:12 đến 21:39 (UTC) ngày 17 tháng 7 năm 2020, trong 27 phút, tổng lưu lượng trên mạng Cloudflare giảm khoảng 50%. Ảnh hưởng chỉ giới hạn ở các điểm hiện diện (PoP) tại một số thành phố ở Mỹ, châu Âu, Nga và Brazil có kết nối vào backbone; các PoP khác vẫn bình thường. Sự cố trên đoạn backbone Newark–Chicago làm đoạn Atlanta–Washington bị nghẽn, nên một kỹ sư đã sửa cấu hình router để giảm bớt lưu lượng backbone đi qua Atlanta. Lẽ ra phải tắt toàn bộ mục chính sách (term), nhưng kỹ sư chỉ tắt điều kiện bên trong nó (prefix-list), khiến router Atlanta quảng bá mọi tuyến BGP với mức ưu tiên cao hơn (local-preference 200) ra toàn bộ backbone. Mức ưu tiên mà mỗi PoP đặt cho tuyến đến server của chính nó là 100, nên toàn bộ lưu lượng của các PoP nối vào backbone dồn về Atlanta. Atlanta bị quá tải, còn các PoP bị ảnh hưởng gần như không còn lưu lượng để xử lý. Hệ thống phục hồi sau khi router Atlanta được tách khỏi backbone. Cloudflare cho biết sự cố không liên quan đến tấn công hay xâm nhập.

Nếu chỉ người chơi ở một thành phố hoặc khu vực cùng lúc bị mất kết nối hoặc không vào được·kẹt loading, còn những nơi khác vẫn bình thường, hãy nghi ngờ trước tiên thay đổi cấu hình định tuyến vừa thực hiện. Trên đồ thị, CPU và lưu lượng chỉ vọt lên ở một PoP, còn các PoP bị ảnh hưởng thì ngược lại rơi xuống gần 0. Bên phụ trách chính là đội hạ tầng (mạng); nếu sự cố nằm ở phía nhà cung cấp thì bên phụ trách chính là bên ngoài. Cloudflare quyết định đặt giới hạn số tuyến có thể nhận (maximum-prefix) trên các phiên BGP của backbone, và điều chỉnh mức ưu tiên để một PoP không thể kéo lưu lượng của PoP khác về mình. Bài gốc

Fastly 2021: Fastly: lỗi CDN trên toàn cầu

Nhiều game phân phối file bản cập nhật, launcher và trang web qua CDN, nên đây là kiểu sự cố hạ tầng mà game cũng bị ảnh hưởng theo. 85% mạng Fastly trả về lỗi từ 09:47 (UTC) ngày 8 tháng 6 năm 2021. Trong vòng 49 phút, 95% mạng đã hoạt động bình thường trở lại, và sự cố được khắc phục xong lúc 12:35. Bản phần mềm bắt đầu triển khai từ ngày 12 tháng 5 chứa một lỗi, chỉ kích hoạt khi một cấu hình khách hàng cụ thể gặp một điều kiện cụ thể. Ngày 8 tháng 6, một khách hàng đẩy lên một thay đổi cấu hình hoàn toàn hợp lệ, và điều kiện đó khớp đúng. Fastly phát hiện bất thường trong vòng 1 phút; sau khi tìm ra và tắt cấu hình khách hàng gây lỗi, hệ thống bắt đầu phục hồi. Việc triển khai bản sửa lỗi bắt đầu lúc 17:25 cùng ngày.

Ngay cả code đã triển khai được vài tuần, khi gặp một điều kiện hiếm cũng có thể lập tức gây sự cố toàn cầu. Ở phía game, tín hiệu cần kiểm tra là tỷ lệ lỗi HTTP của các yêu cầu tải bản cập nhật, launcher và web cùng tăng ở mọi khu vực, và trang trạng thái của nhà cung cấp CDN. Đặc điểm nhận biết là các kết nối game đã vào sẵn vẫn bình thường nếu không đi qua CDN, chỉ có kết nối mới, tải bản cập nhật và đăng nhập web bị chặn. Bên phụ trách chính là bên ngoài (nhà cung cấp CDN); đội phát triển game và đội hạ tầng nên chuẩn bị sẵn đường vòng như dùng từ hai CDN trở lên hoặc tải thẳng từ server gốc (origin). Bài gốc

Meta 2021: Facebook: một lệnh trên backbone làm biến mất cả DNS

Đây là sự cố hạ tầng có thể xảy ra y hệt với mạng riêng và DNS của công ty game. Ngày 4 tháng 10 năm 2021, các dịch vụ của Facebook (nay là Meta) không truy cập được trên toàn thế giới. Toàn bộ backbone nối các trung tâm dữ liệu bị đứt, và từ phía Internet không còn tìm thấy server DNS của Facebook. Bài tổng kết không ghi sự cố kéo dài bao lâu. Trong một đợt bảo trì định kỳ, một lệnh chạy để kiểm tra dung lượng backbone toàn cầu đã vô tình cắt mọi kết nối của backbone, còn công cụ audit lẽ ra phải chặn những lệnh như vậy thì không chặn được vì có lỗi. Server DNS ở các cơ sở quy mô nhỏ được thiết kế để tự coi mình là bất thường và rút quảng bá BGP khi không liên lạc được với trung tâm dữ liệu, nên dù server DNS vẫn chạy, từ Internet không thể truy cập tới chúng. Cả đường truy cập thông thường lẫn đường truy cập ngoài băng (out-of-band) đều bị đứt, công cụ nội bộ cũng mất DNS, nên phải cử kỹ sư đến tận trung tâm dữ liệu, và quy trình bảo mật khiến việc này mất thêm thời gian. Khi phục hồi, điện năng tiêu thụ ở mỗi trung tâm dữ liệu đã giảm hàng chục MW; Meta đánh giá rằng bật lại toàn bộ cùng lúc có thể gây rủi ro từ hệ thống điện cho đến cache, nên đã tăng tải theo từng bước.

Khi mọi khu vực và mọi nhà mạng cùng lúc gặp tình trạng không vào được·kẹt loading, hãy xem DNS và tuyến BGP trước khi xem server game. Việc này kiểm tra được cả từ bên ngoài công ty, bằng truy vấn DNS qua resolver bên ngoài và thông tin tuyến BGP công khai. Bên phụ trách chính là đội hạ tầng (mạng). Hãy kiểm tra trước xem đường truy cập ngoài băng và công cụ nội bộ dùng khi có sự cố có phụ thuộc vào cùng DNS và mạng đó hay không, và khi phục hồi, tăng tải theo từng bước để lượt kết nối lại không dồn đến cùng lúc. Bài gốc

AWS 2021: AWS us-east-1: tắc nghẽn mạng nội bộ

Nhiều game đặt server, hệ thống đăng nhập và dữ liệu trên public cloud, nên đây là kiểu sự cố hạ tầng mà game cũng bị ảnh hưởng theo. Lúc 7:30 sáng ngày 7 tháng 12 năm 2021 (giờ chuẩn Thái Bình Dương), mạng nội bộ của region Bắc Virginia (us-east-1) bị tắc nghẽn. Từ 7:33, lỗi và độ trễ của EC2 API tăng lên khiến việc khởi tạo instance mới gặp khó khăn (khởi tạo instance phục hồi lúc 2:40 chiều), kéo theo đăng nhập console thất bại, không thay đổi được cấu hình Route 53, chỉ số CloudWatch bị trễ và mất một phần. Thiết bị mạng phục hồi hoàn toàn lúc 2:22 chiều. Các instance EC2 đang chạy sẵn và các phản hồi DNS hiện có không bị ảnh hưởng. Một tác vụ tự động nhằm tăng dung lượng cho một dịch vụ nằm trên mạng chính đã gây ra hành vi không lường trước ở rất nhiều client trong mạng nội bộ, làm số lần thử kết nối tăng vọt. Thiết bị nối mạng nội bộ với mạng chính bị quá tải nên việc truyền thông bị trễ, và độ trễ này lại làm tăng thêm số lần thử kết nối và thử lại, khiến tắc nghẽn kéo dài. Các client có cơ chế backoff (giãn khoảng cách giữa các yêu cầu khi tắc nghẽn), nhưng một lỗi tiềm ẩn khiến cơ chế này không hoạt động đúng. Hệ thống giám sát nội bộ cũng phụ thuộc vào chính mạng đó, nên đội vận hành phải xử lý dựa vào log mà không có chỉ số thời gian thực.

Nếu lượt thử lại không giãn khoảng cách, một đợt tắc nghẽn ngắn sẽ thành sự cố kéo dài hàng giờ. Nhìn từ phía game, dù server game đang chạy sẵn vẫn bình thường, việc thêm server mới (autoscaling), các chức năng đăng nhập, ghép trận và thanh toán dùng API của cloud, cùng hệ thống giám sát đều có thể bị chặn theo. Tín hiệu cần kiểm tra là trang trạng thái của nhà cung cấp cloud, tỷ lệ lỗi API của cloud và số lần khởi tạo instance thất bại. Bên phụ trách chính là bên ngoài (nhà cung cấp cloud). Đội phát triển game đặt exponential backoff với khoảng chờ ngẫu nhiên và giới hạn số lần cho mọi lượt thử lại; đội hạ tầng chuẩn bị dung lượng dự phòng đủ để trụ được khi không mở rộng được, cùng phương án chuyển sang region khác. Bài gốc

Cloudflare 2025: Cloudflare: sự cố DNS công cộng 1.1.1.1

Đây là sự cố của một DNS resolver công cộng mà người dùng tự cấu hình trên thiết bị hoặc router. Ở kiểu sự cố này, chỉ những người dùng cấu hình này bị chặn truy cập cùng lúc mọi game và dịch vụ. Từ 21:52 đến 22:54 (UTC) ngày 14 tháng 7 năm 2025, trong 62 phút, resolver 1.1.1.1 không phản hồi trên toàn thế giới. Cloudflare cho biết với nhiều người dùng, điều này đồng nghĩa với việc gần như không dùng được bất kỳ dịch vụ Internet nào. Các truy vấn qua UDP, TCP và DNS over TLS bị ảnh hưởng, còn DNS over HTTPS (kết nối bằng tên miền) tương đối ổn định. Ngày 6 tháng 6, khi chuẩn bị service topology (cấu hình quy định dải IP được quảng bá từ những PoP nào) cho một dịch vụ khác sẽ dùng trong tương lai, dải IP của resolver 1.1.1.1 đã vô tình bị gắn vào cấu hình đó. Ngày 14 tháng 7, khi cấu hình của dịch vụ kia được thay đổi, số PoP quảng bá dải IP của resolver giảm từ tất cả các nơi xuống còn một PoP đang offline, và tuyến BGP bị rút trên toàn thế giới. Thay đổi này lan ngay ra mọi trung tâm dữ liệu mà không qua triển khai canary. Lúc 22:20, cấu hình được hoàn tác và lưu lượng hồi lại khoảng 77%, nhưng trong lúc đó khoảng 23% server edge đã bị xóa mất cấu hình IP cần thiết, phải cấu hình lại, nên đến 22:54 mới bình thường. Cloudflare cho biết đây là lỗi cấu hình nội bộ, không liên quan đến tấn công hay BGP hijacking.

Nếu server game và những người chơi khác vẫn bình thường mà chỉ một số người chơi gặp tình trạng không vào được·kẹt loading với server đăng nhập hoặc server bản cập nhật, hãy nghi ngờ DNS mà những người chơi đó đang dùng. Đặc điểm nhận biết là các phiên đã kết nối vẫn được giữ, chỉ kết nối mới thất bại. Chỉ cần hướng dẫn người chơi đổi cấu hình DNS hoặc tự tra địa chỉ server là phân định được ngay. Bên phụ trách chính là bên ngoài (đơn vị vận hành DNS, nhà mạng). Nếu đội phát triển game (client) hiển thị lỗi phân giải tên miền tách biệt với các lỗi khác, bộ phận chăm sóc khách hàng có thể kết luận ngay. Bài gốc

AWS 2025: AWS us-east-1: sự cố DNS của DynamoDB và quá trình phục hồi kéo dài

Nhiều game đặt server, hệ thống đăng nhập và dữ liệu trên public cloud, nên đây là kiểu sự cố hạ tầng mà game cũng bị ảnh hưởng theo. Từ 11:48 tối ngày 19 tháng 10 năm 2025 đến 2:20 chiều ngày 20 (giờ mùa hè Thái Bình Dương), region Bắc Virginia chịu ảnh hưởng qua ba giai đoạn. Lỗi DynamoDB API tăng cho đến 2:40 sáng ngày 20; từ 2:25 sáng đến 10:36 sáng, việc khởi tạo instance EC2 mới thất bại (vấn đề kết nối của một số instance mới được giải quyết lúc 1:50 chiều); và từ 5:30 sáng đến 2:09 chiều, lỗi kết nối của một số Network Load Balancer (NLB) tăng lên. Hệ thống tự động quản lý DNS của DynamoDB có một race condition tiềm ẩn. Trong số các bộ thực thi (DNS Enactor) áp dụng kế hoạch DNS ở các availability zone khác nhau, một bộ bị chậm bất thường đã ghi đè kế hoạch mới bằng một kế hoạch cũ; ngay sau đó, tác vụ dọn dẹp của một bộ thực thi khác xóa kế hoạch cũ này, làm bản ghi DNS của endpoint theo region (dynamodb.us-east-1.amazonaws.com) trở thành rỗng. Hệ thống tự động không tự sửa được nên phải có người khôi phục thủ công. Hệ thống quản lý server vật lý của EC2 phụ thuộc vào DynamoDB, nên trong thời gian đó, lease mà mỗi server vật lý duy trì đã hết hạn. Sau khi DynamoDB hoạt động trở lại, do có quá nhiều server vật lý, việc thiết lập lại lease bị timeout trước khi hoàn tất và các tác vụ thử lại lại dồn lên, đưa hệ thống vào trạng thái “sụp đổ do tắc nghẽn (congestive collapse)”. Cấu hình mạng của các instance mới khởi tạo lan truyền chậm, khiến health check của NLB lúc thành công lúc thất bại, và cả các node bình thường cũng liên tục bị loại khỏi DNS rồi được đưa trở lại.

Lỗi bản ghi DNS ở một nơi lan sang các dịch vụ khác phụ thuộc vào dịch vụ đó, và ngay cả khi nguyên nhân đã được gỡ, tác vụ tồn đọng cùng health check chập chờn vẫn khiến việc phục hồi mất thêm vài giờ. Nhìn từ phía game, các server đang chạy sẵn vẫn trụ được, nhưng không khởi tạo được server mới nên autoscaling ngừng lại, và khi health check chập chờn, bộ cân bằng tải có thể loại bỏ cả những server đang bình thường. Tín hiệu cần kiểm tra là trang trạng thái của cloud, tỷ lệ lỗi API của các dịch vụ được quản lý (managed service), số lần khởi tạo instance thất bại và số target khỏe mạnh của bộ cân bằng tải. Bên phụ trách chính là bên ngoài (nhà cung cấp cloud); đội hạ tầng giới hạn số server có thể bị loại cùng lúc do health check thất bại và chuẩn bị phương án chuyển sang region khác. Bài gốc

T4Công cụ

Hướng dẫn báo lag

Phần tốn thời gian nhất khi đội phát triển game và đội hạ tầng tìm nguyên nhân là xác định “khi nào, ở đâu, ai”. Nếu bạn điền các mục dưới đây, họ có thể tìm ngay đúng khoảnh khắc đó trong log và đồ thị.

T5Công cụ

Thuật ngữ

Đây là những từ hay gặp khi trao đổi với đội phát triển game và đội hạ tầng. Hãy thử gõ tiếng Việt hoặc tiếng Anh vào ô tìm kiếm.

Ping Ping, RTT
Thời gian để tín hiệu bạn gửi đi tới server rồi quay về (khứ hồi). Ping hiển thị trong game đôi khi còn lẫn cả thời gian chờ xử lý trên server.
Độ trễ Latency
Thời gian gói tin đi từ lúc xuất phát đến lúc tới nơi. Thường chỉ tính một chiều nên vào khoảng một nửa ping.
Jitter Jitter
Độ dao động của khoảng cách giữa các lần gói tin đến. Dù ping trung bình như nhau, jitter lớn thì màn hình vẫn giật khựng.
Gói tin Packet
Một khối dữ liệu gửi qua mạng trong một lần. Thường tối đa 1.500 byte; một bản cập nhật trạng thái của game chỉ vài chục đến vài trăm byte.
Mất gói tin Packet loss
Gói tin đã gửi nhưng không tới được nơi nhận, bị mất giữa đường. Với game dùng TCP, chỉ 1% thôi là cứ vài giây đến hơn chục giây lại thấy khựng một lần; game dùng UDP có nội suy và gửi lặp input thì có khi che được tới vài %.
Băng thông Bandwidth
Lượng dữ liệu tối đa đường truyền gửi được trong 1 giây (Mbps). Đây là khái niệm khác với việc dữ liệu đến nhanh hay chậm (độ trễ).
Tick Tick
Đơn vị một lần server tính toán trạng thái game. Server 20 tick tính 20 lần trong 1 giây, tức cứ 50 ms một lần.
Tick rate Tick rate
Số tick chạy trong 1 giây. Càng cao thì phản hồi càng nhanh nhưng chi phí server và lượng dữ liệu truyền đi càng tăng. Để tiết kiệm lượng dữ liệu, số lần gửi gói tin đôi khi được đặt thấp hơn tick rate.
Tick budget Tick budget
Thời gian tối đa để hoàn thành một tick. Vượt quá thì tick sau bị trễ và khoảng cách giữa các tick giãn ra.
FPS Frames per second
Số lần vẽ màn hình trong 1 giây. 60 FPS nghĩa là mỗi khung hình có 16,7 ms.
Frame time Frame time
Thời gian để vẽ một khung hình. Với cảm nhận của người chơi, những khung hình thỉnh thoảng vọt lên quan trọng hơn FPS trung bình.
Snapshot Snapshot
Bản tóm tắt “trạng thái game lúc này” mà server gửi mỗi tick, gồm vị trí, máu, trạng thái… Thường chỉ gửi phần khác với trạng thái bên nhận đã có (nén delta).
Nội suy Interpolation
Kỹ thuật vẽ nối giữa hai snapshot đã nhận để chuyển động trông mượt. Đổi lại, thứ bạn thấy là quá khứ một chút.
Bộ đệm nội suy Interpolation buffer
Khoảng thời gian cố ý vẽ trễ để nội suy. Đây là phần dự phòng để hấp thụ jitter và một hai lần mất gói. Thường bằng 2 lần khoảng cách giữa các gói (nhận 20 lần trong 1 giây thì là 100 ms); có game tự tăng lên khi jitter lớn.
Ngoại suy Extrapolation, Dead reckoning
Kỹ thuật đoán vị trí sắp tới dựa trên vận tốc cuối cùng khi chưa có gói tin mới. Đoán sai sẽ trông như dịch chuyển tức thời, nên nhiều game chỉ đoán tới khoảng 0,25 giây rồi dừng (mặc định của Source Engine là 0,25 giây).
Dự đoán phía client Client-side prediction
Kỹ thuật cho nhân vật của bạn di chuyển trước trên màn hình mà không chờ server xác nhận.
Hiệu chỉnh theo server Reconciliation
Khi kết quả từ server về, game so với phần đã dự đoán rồi sửa lại vị trí nhân vật của bạn. Game lấy vị trí server đã xác nhận, áp dụng lại các input chưa được xác nhận rồi tính lại. Chênh lệch lớn thì trông như kéo ngược.
Bù trễ Lag compensation
Kỹ thuật mà khi phán định đòn đánh, server quay ngược về thời điểm quá khứ người tấn công đang thấy để kiểm tra có trúng hay không. Để người bị đánh không chịu thiệt, biên độ quay ngược có giới hạn trên. Game bắn súng đối kháng thường khoảng 0,2–0,25 giây; cũng có trường hợp quay ngược tới 1 giây như mặc định của Source Engine.
Server có thẩm quyền Authoritative server
Thiết kế trong đó chỉ server mới đưa ra phán định cuối cùng. Cách này chống gian lận nhưng mọi kết quả đều phải qua một vòng khứ hồi tới server, vì vậy game dùng dự đoán và hiển thị trước để che thời gian chờ.
Lockstep Deterministic lockstep
Cách mọi người chỉ trao đổi input rồi cùng tính giống hệt nhau trong cùng một lượt. Input được cộng thêm một độ trễ cố định, và chỉ cần input của một người đến muộn là tất cả phải chờ.
Bộ đệm input phía server Server-side input buffer
Bộ đệm nơi server gom một ít input của từng người rồi mỗi tick lấy ra dùng một cái. Người có jitter lớn vẫn trông mượt trong mắt người khác, nhưng thời điểm hành động của người đó được server chốt cũng trễ đi tương ứng.
Listen server Listen server
Cách PC của một người chơi vừa chơi game vừa kiêm luôn vai trò server. Chủ phòng có ping bằng 0, nhưng đường truyền hay PC của chủ phòng chậm thì mọi người đều bị lag.
Phasing Phasing
Tính năng cho cùng một địa điểm hiển thị NPC và địa hình khác nhau tùy tiến độ nhiệm vụ. Nếu hai nhân vật có tiến độ khác nhau thì việc chỉ một bên không thấy NPC là bình thường.
Rollback netcode Rollback netcode (GGPO)
Cách dự đoán input của đối thủ để chạy trước, nếu input thật khác đi thì quay lại khung hình trong quá khứ và tính lại. Dùng nhiều trong game đối kháng. Thuật ngữ này khác với rollback của DB.
Buffer input Input buffer, spell queue
Nhận trước input tiếp theo được bấm ngay trước khi hồi chiêu hoặc động tác kết thúc, rồi thực hiện đúng lúc kết thúc. Nhờ vậy giữa các đòn liên hoàn không bị chen thêm thời gian khứ hồi.
Hiển thị trước Client-side feedback
Phát trước hoạt ảnh, âm thanh, hiệu ứng mà không chờ server xác nhận. Chỉ những kết quả cần chốt như sát thương hay phần thưởng mới chờ server trả lời. Nếu server từ chối thì phải hoàn tác những gì đã hiển thị.
TCP Transmission Control Protocol
Giao thức chuyển dữ liệu đúng thứ tự, không thiếu gói nào. Khi mất gói, TCP giữ lại các gói phía sau, không chuyển cho game cho đến khi nhận lại được gói đó.
UDP User Datagram Protocol
Giao thức gửi đi thế nào thì chuyển thế ấy, không bảo đảm gì. Không phải chờ, đổi lại game phải tự xử lý mất gói và thứ tự.
UDP tin cậy Reliable UDP (KCP, ENet…)
Cách tự cài đặt trên nền UDP phần truyền lại và bảo đảm thứ tự, chỉ ở mức vừa đủ dùng.
HOL blocking Head-of-line blocking
Hiện tượng một gói phía trước bị kẹt khiến mọi gói phía sau phải chờ. Đây là nguyên nhân gây tua nhanh với TCP.
RTO Retransmission timeout
Timer truyền lại. Khoảng thời gian TCP chờ trước khi xác định gói tin đã mất và gửi lại. Trên Linux là ping + 200 ms trở lên, mỗi lần thất bại lại tăng gấp đôi.
Thuật toán Nagle Nagle’s algorithm
Tính năng của TCP gom dữ liệu nhỏ lại cho đến khi nhận được xác nhận (ACK) cho dữ liệu đã gửi trước đó, rồi gửi một lần để tiết kiệm số gói. Với game thường nên tắt.
TCP_NODELAY TCP_NODELAY
Tùy chọn socket để tắt thuật toán Nagle. Message nhỏ được gửi đi ngay.
Delayed ACK Delayed ACK
Tính năng gửi xác nhận đã nhận muộn một chút, gộp chung với dữ liệu khác. Linux thường là 40 ms (tối đa 200 ms); Windows bản cũ là 200 ms, bản gần đây là 40 ms.
Bộ đệm socket SO_SNDBUF / SO_RCVBUF
Kích thước vùng chờ gửi và nhận mà OS cấp cho từng socket. Quá nhỏ thì bị tràn, quá lớn thì dữ liệu cũ chất đống và phải chờ.
keepalive SO_KEEPALIVE
Tính năng của TCP kiểm tra xem kết nối nhàn rỗi còn sống hay không. Mặc định tắt, và dù bật thì theo mặc định cũng phải sau 2 giờ mới kiểm tra.
RST TCP reset
Tín hiệu TCP cắt kết nối ngay lập tức. Dữ liệu chưa kịp gửi sẽ bị bỏ.
Heartbeat Heartbeat
Tín hiệu “vẫn còn sống” do chính game gửi định kỳ. Dùng để phát hiện kết nối đã đứt và giữ cho kết nối trên các thiết bị trung gian không bị xóa.
Timeout Timeout
Ngưỡng thời gian mà nếu không có phản hồi thì coi là thất bại. Quá ngắn thì báo nhầm, quá dài thì phát hiện muộn.
NAT Network Address Translation
Tính năng của router cho nhiều thiết bị trong nhà đi ra ngoài bằng chung một IP công cộng, đồng thời ghi lại từng kết nối vào bảng NAT.
CGNAT Carrier-grade NAT
NAT quy mô lớn do nhà mạng vận hành, cho nhiều thuê bao dùng chung một IP.
MTU Maximum Transmission Unit
Kích thước gói tin tối đa gửi được trong một lần. Thường là 1.500 byte, nhỏ hơn trên các chặng VPN hay PPPoE.
Bufferbloat Bufferbloat
Hiện tượng thiết bị giữ hàng đợi quá lớn khiến độ trễ tăng lên hàng trăm ms.
SQM Smart Queue Management (fq_codel, CAKE)
Tính năng của router giữ hàng đợi ngắn và đẩy dữ liệu ra công bằng theo từng luồng. Giải pháp cho bufferbloat.
QoS Quality of Service
Tính năng đặt mức ưu tiên để lưu lượng quan trọng được gửi trước.
Peering Peering
Điểm các nhà mạng kết nối mạng của nhau. Dễ bị nghẽn vào buổi tối.
BGP Border Gateway Protocol
Giao thức các nhà mạng dùng để báo cho nhau nên gửi dữ liệu theo tuyến đường nào trên Internet. Khi thay đổi, tuyến đường và ping cũng đổi theo.
DDoS Distributed Denial of Service
Kiểu tấn công gửi lượng lưu lượng khổng lồ từ nhiều nơi để làm tê liệt dịch vụ.
Trung tâm lọc DDoS DDoS scrubbing center
Cơ sở của nhà cung cấp dịch vụ chống DDoS. Khi bị tấn công, lưu lượng hướng tới server được đưa qua đây trước để lọc bỏ tấn công, chỉ lưu lượng hợp lệ được chuyển tiếp. Nếu cơ sở này ở xa thì tuyến đường dài ra.
Tường lửa Firewall
Thiết bị hoặc phần mềm chỉ cho các kết nối được phép đi qua. Tường lửa theo dõi các kết nối bằng bảng phiên.
Bộ cân bằng tải Load balancer
Thiết bị chia các kết nối đi vào cho nhiều server.
Bảng phiên Session table, conntrack
Bảng mà thiết bị hoặc OS dùng để theo dõi các kết nối hiện có. Kích thước có giới hạn.
Microburst Microburst
Hiện tượng lưu lượng dồn đến trong một khoảnh khắc cực ngắn, dưới 1 ms, dù mức trung bình thấp.
NIC Network Interface Card
Card mạng của server.
Ring buffer Ring buffer
Bộ đệm giữ các gói tin NIC đã nhận cho đến khi CPU lấy đi. Bộ đệm này dùng xoay vòng một số slot cố định; khi mọi slot đã đầy thì gói tin mới bị bỏ.
Ngắt Interrupt
Tín hiệu thiết bị gửi tới CPU để báo “có việc cần xử lý”.
RSS Receive Side Scaling
Tính năng của NIC chia các gói tin nhận được vào nhiều hàng đợi nhận để nhiều core CPU cùng xử lý.
PPS Packets per second
Số gói tin mỗi giây. Server game thường chạm giới hạn ở con số này trước cả băng thông.
Kernel Kernel
Phần lõi của hệ điều hành, phụ trách mạng, bộ nhớ và việc phân chia CPU.
backlog Listen backlog
Hàng đợi chứa các yêu cầu kết nối mới mà server chưa nhận vào. Khi hàng đợi đầy, Linux lặng lẽ bỏ yêu cầu mới, còn Windows gửi phản hồi từ chối.
TIME_WAIT TIME_WAIT
Trạng thái mà bên đóng kết nối trước giữ lại cặp cổng đó một lúc (Linux là 60 giây) để phòng gói tin đến muộn.
CPU steal Steal time
Thời gian máy ảo muốn dùng CPU nhưng phải chờ vì server vật lý đang cấp CPU cho máy ảo khác. Xem bằng giá trị st trong top.
CPU throttling CFS throttling
Cơ chế buộc container dừng đến hết chu kỳ khi đã dùng hết quota CPU trong một chu kỳ cố định (CFS period, thường 100 ms).
File descriptor File descriptor
Số được gắn cho mỗi tệp hoặc kết nối mà tiến trình mở (fd). Số lượng có giới hạn.
Thread Thread
Đơn vị công việc chạy độc lập bên trong một chương trình. Nhiều thread có thể chạy cùng lúc.
Context switch Context switch
Việc CPU đổi thread đang chạy sang thread khác. Việc này tốn chi phí.
Lock Lock, Mutex
Cơ chế khóa chỉ cho một thread dùng dữ liệu chung tại một thời điểm.
Deadlock Deadlock
Trạng thái các thread chờ lock của nhau nên cùng dừng mãi mãi.
Thread pool Thread pool
Nhóm worker thread tạo sẵn. Khi tất cả đều bận, việc mới phải chờ.
I/O bất đồng bộ epoll, IOCP, io_uring
Cách để chương trình làm việc khác trong lúc nhập xuất đang diễn ra, khi xong thì nhận thông báo.
AOI Area of Interest
“Phạm vi nhìn thấy được” của từng người chơi. Chỉ gửi các thay đổi trong phạm vi này để giảm lượng dữ liệu. Để giảm chi phí xác định ai ở trong phạm vi, bản đồ thường được chia thành lưới (grid) và chỉ xét các ô ở gần.
Broadcast Broadcast, fan-out
Gửi một thay đổi tới nhiều người có thể thấy nó. Nếu mọi người tụ tập đều thấy nhau thì lượng phải gửi tăng theo bình phương số người.
GC Garbage collection
Tính năng tự động thu hồi bộ nhớ đã dùng xong. Trong lúc GC chạy, chương trình có thể bị dừng.
Heap Heap
Vùng bộ nhớ mà chương trình xin cấp mỗi khi cần trong lúc chạy.
Rò rỉ bộ nhớ Memory leak
Lỗi không trả lại bộ nhớ đã dùng xong khiến mức sử dụng tăng mãi. Dù có GC, lỗi này vẫn xảy ra nếu đối tượng đã dùng xong vẫn bị tham chiếu ở đâu đó.
Swap Swap, paging
Khi thiếu RAM, một phần bộ nhớ được chuyển tạm xuống ổ đĩa. Khi cần dùng lại phần bộ nhớ đó thì chậm hơn RAM trên 1.000 lần.
OOM killer Out-of-memory killer
Khi hết bộ nhớ, Linux chọn tiến trình dùng nhiều bộ nhớ nhất và buộc nó kết thúc. Với container, chỉ cần chạm giới hạn bộ nhớ là cơ chế này đã chạy.
Cache miss Cache miss
Dữ liệu không có trong cache gần CPU nên phải đi tới bộ nhớ chậm hơn.
IOPS I/O operations per second
Số lần đọc, ghi ổ đĩa xử lý được trong 1 giây. Ổ đĩa cloud có giới hạn tùy theo số tiền bạn trả.
fsync fsync
Lệnh chờ đến khi dữ liệu chắc chắn đã được ghi xuống ổ đĩa. Thao tác ghi thông thường được giữ trong bộ nhớ của OS trước rồi mới ghi xuống ổ đĩa sau, nên nếu server mất điện trong khoảng đó thì dữ liệu có thể mất. fsync an toàn nhưng chậm.
Burst credit Burst credits
Lượng tích lũy cho phép ổ đĩa hay server trên cloud tạm thời chạy vượt mức hiệu năng cơ bản. Hết tích lũy thì tụt về hiệu năng cơ bản.
Index Index
Chỉ mục của DB. Không có index thì phải đọc toàn bộ bảng.
Full scan Full table scan
Truy vấn kiểm tra mọi dòng trong bảng mà không dùng index.
Kế hoạch thực thi Query plan
Cách DB quyết định sẽ giải một query theo thứ tự nào, dùng index nào. Code không đổi nhưng DB đổi kế hoạch thì cùng một query cũng có thể đột ngột chậm đi.
Transaction Transaction
Nhóm thao tác DB gói thành một khối “hoặc thành công hết, hoặc không có gì”. Giao dịch trong game bắt buộc phải xử lý bằng transaction. Transaction khóa các dòng đã sửa cho đến khi kết thúc nên càng ngắn càng tốt.
Connection pool Connection pool
Nhóm kết nối DB tạo sẵn. Khi tất cả đang được dùng, yêu cầu mới phải chờ.
Hot row Hot row
Một dòng mà rất nhiều yêu cầu cùng muốn sửa một lúc. Nguyên nhân gây tranh chấp khóa.
Replication lag Replication lag
Khoảng thời gian DB bản sao bị tụt lại phía sau DB chính.
Rollback Rollback
Việc lưu bị hủy và dữ liệu quay về trạng thái trước đó. Người chơi sẽ thấy “vật phẩm biến mất”.
Cache Cache (Redis etc.)
Bản sao của dữ liệu hay dùng, đặt ở nơi truy cập nhanh. Giúp giảm tải cho DB.
Checkpoint Checkpoint
Việc DB định kỳ ghi dồn các thay đổi đang gom trong bộ nhớ xuống ổ đĩa. Vào lúc đó, việc lưu và truy vấn có thể chậm đi một chút.
Failover Failover
Việc chuyển sang bản dự phòng khi server hoặc DB chính chết. Trong lúc chuyển, tạm thời không lưu được dữ liệu, và nếu replication đang trễ thì dữ liệu cuối cùng có thể bị mất.
MVCC Multi-version concurrency control
Cách DB tạm giữ các phiên bản cũ để người đọc và người sửa không chặn nhau. Nếu có transaction mở quá lâu, phiên bản cũ chất đống và làm DB chậm đi.
Cache stampede Cache stampede
Hiện tượng cache bị trống cùng lúc khiến yêu cầu dồn về nguồn gốc (DB).
Gateway Gateway
Server trung gian nhận kết nối từ client rồi chuyển tiếp tới các server game phía sau.
Circuit breaker Circuit breaker
Cơ chế tạm ngắt lời gọi tới dịch vụ đang liên tục lỗi và trả lỗi ngay để ngăn sự cố dây chuyền. Sau một lúc, cơ chế này thử gọi một hai lần; nếu dịch vụ đã hồi phục thì cho phép gọi lại.
Sự cố dây chuyền Cascading failure
Sự cố ở một nơi lan sang các dịch vụ khác theo chuỗi gọi.
Autoscaling Autoscaling
Tính năng tự động tăng, giảm số server theo tải. Việc tăng thêm server cần có thời gian.
Watchdog Watchdog
Timer giám sát xem server có bị đứng không. Nếu vòng lặp game dừng quá thời gian quy định (vài giây đến vài chục giây), watchdog ghi lại trạng thái (dump) rồi buộc server kết thúc để khởi động lại.
Mức sử dụng Utilization
Tỷ lệ thời gian worker (chủ thể xử lý yêu cầu như core CPU, thread, kết nối DB) bận. Vượt 80–90% thì thời gian chờ tăng vọt.
p99 99th percentile
Giá trị mà 99 trên 100 lần nhanh hơn nó và khoảng 1 lần chậm hơn nó. Phản ánh lag người chơi cảm nhận tốt hơn giá trị trung bình.
V-Sync Vertical sync
Tính năng xuất khung hình theo đúng chu kỳ làm tươi của màn hình. Loại bỏ được hiện tượng xé hình nhưng gây trễ thao tác, và khi FPS tụt dưới tần số quét thì có thể nhảy qua lại giữa 60 và 30 gây giật khựng.
Tần số quét biến thiên VRR, G-Sync, FreeSync
Tính năng cho màn hình đổi hình đúng lúc khung hình sẵn sàng. Giảm giật khựng và trễ thao tác sinh ra khi V-Sync nhảy qua lại giữa 60 và 30.
Anti-cheat Anti-cheat
Module bảo mật chống hack game. Khi việc kiểm tra định kỳ hoặc heartbeat với server thất bại, anti-cheat có thể gây giật khựng hoặc mất kết nối.
Overlay Overlay
Tính năng vẽ đè lên màn hình game của các chương trình nhắn tin, quay màn hình hay hiển thị FPS. Vì chen vào quá trình vẽ của game nên có thể gây giật khựng.
Biên dịch shader Shader compilation
Việc chuyển chương trình hiệu ứng đồ họa sang dạng dành cho GPU. Nếu không làm trước thì màn hình khựng ở lần đầu nhìn thấy hiệu ứng; cập nhật driver đồ họa làm kết quả đã lưu mất hiệu lực nên phải làm lại.
Main thread Main thread, Game thread
Thread trung tâm của game, lần lượt xử lý việc tính luật chơi và chuẩn bị màn hình. Chỉ cần một việc ở đây tốn nhiều thời gian là trong lúc đó màn hình đứng lại.
Độ phân giải timer Timer resolution
Khoảng ngắn nhất mà hệ điều hành có thể đánh thức chương trình đang ngủ. Mặc định của Windows là 15,6 ms, nên nếu chương trình không tự đổi thì dù yêu cầu “1 ms nữa đánh thức tôi” vẫn bị đánh thức muộn.
Bóp xung do nhiệt Thermal throttling
Tính năng bảo vệ: thiết bị nóng lên thì tự giảm tốc độ CPU, GPU. Trên điện thoại, chơi game vài phút đến vài chục phút là thường xảy ra.
VRAM Video memory
Bộ nhớ riêng gắn trên card đồ họa. Texture và model được nạp vào đây để vẽ. Thiếu VRAM thì phải trao đổi với bộ nhớ của PC qua đường chậm nên bị giật khựng.
Net graph Net graph
Bảng hiển thị dành cho phát triển và debug, vẽ đồ thị thời gian thực của ping, mất gói, FPS, tick ngay trên màn hình game. Nếu quay được cùng trong video báo lag thì tìm nguyên nhân dễ hơn nhiều.
Tỷ lệ truyền lại Retransmission rate
Tỷ lệ gói TCP phải gửi lại trên tổng số đã gửi. Không có chuẩn chính thức, nhưng trung bình toàn server dưới 0,1% là khá khỏe, còn vượt 1% thì nhiều người chơi dễ thấy lag. Cũng nên xem giá trị đã tăng gấp mấy lần so với bình thường.
SACK Selective ACK
Tính năng của TCP cho bên nhận báo chi tiết “đoạn này đã nhận, chỉ thiếu phần này”. Mất nhiều gói vẫn có thể phục hồi trong một lượt.
RACK-TLP Recent ACK, Tail Loss Probe
Tính năng của TCP xác định mất gói dựa trên thời gian, và nếu một lúc không có ACK thì gửi lại gói cuối thêm một lần để phục hồi sớm hơn. Là mặc định trên Linux và Android mới nhất. Windows bật TLP và RACK mặc định từ Windows 10 (1607) và Server 2016; bản RACK mới, phục hồi được cả gói truyền lại bị mất, có từ Server 2022. Chỉ hoạt động trên kết nối đã bật SACK.
Truyền lại không cần thiết Spurious retransmission
Gói tin thật ra vẫn tới, chỉ đến muộn hoặc sai thứ tự, nhưng bị nhầm là đã mất nên bị gửi lại. Việc này lãng phí đường truyền và làm giảm tốc độ gửi một cách vô ích.
Zero window Zero window
Trạng thái bộ đệm bên nhận đã đầy và báo “tạm ngừng gửi”. Trông giống truyền lại nhưng đường truyền vẫn ổn; thực chất là chương trình bên nhận không đọc kịp.
thin stream Thin stream
Kết nối gửi gói nhỏ thưa thớt như game. Tín hiệu để truyền lại nhanh khó gom đủ nên khi mất gói sẽ đứng lâu.
Policer Policer
Kiểu giới hạn tốc độ bỏ ngay các gói vượt tốc độ quy định mà không cho vào hàng đợi. Kiểu cho vào hàng đợi rồi đẩy ra từ từ thì gọi là shaper.
Pacing Pacing
Chia các gói cần gửi ra đều theo thời gian, không đổ ra một lượt. Giúp tránh làm tràn các bộ đệm nhỏ.
ECN Explicit Congestion Notification
Tính năng khi nghẽn thì gắn dấu “đang nghẽn” vào gói tin, không bỏ gói, để bên gửi giảm tốc độ. Báo nghẽn mà không cần mất gói. Chỉ hiệu quả khi cả hai đầu và thiết bị ở chặng bị nghẽn đều hỗ trợ.
MSS Maximum Segment Size
Kích thước dữ liệu tối đa TCP chứa trong một gói. Thường là 1.460 byte; giảm cho khớp với chặng tunnel thì có thể tránh được MTU black hole.
Handover Handover
Việc điện thoại đang di chuyển đổi sang trạm phát sóng khác.
Phân vị Percentile (p50, p95, p99)
Giá trị nằm ở vị trí bao nhiêu phần trăm khi xếp các giá trị từ nhỏ đến lớn. p50 là trung vị, p99 là giá trị quanh 1 lần chậm nhất trong 100 lần. Phân vị cho thấy những lần vọt lên mà giá trị trung bình che mất.
Tail latency Tail latency
Độ trễ dài thỉnh thoảng mới xảy ra dù phần lớn đều nhanh. Gần như không lộ ra trong giá trị trung bình, nhưng đây lại là phần người chơi nhớ là lag.
Giám sát giả lập Synthetic monitoring
Dùng thiết bị hoặc server đo đặt ở vị trí cố định, thay cho người chơi thật, để định kỳ gửi ping, traceroute… và đo chất lượng tuyến đường. RIPE Atlas là công cụ công khai tiêu biểu.
Khoảng gộp dữ liệu Aggregation interval
Một điểm trên đồ thị gộp giá trị của bao nhiêu giây hay bao nhiêu phút. Khoảng càng dài thì các lần vọt lên ngắn càng bị trung bình làm mờ đi.
Postmortem Postmortem
Bài viết tổng kết sau khi sự cố kết thúc: chuyện gì đã xảy ra, vì sao, và sẽ thay đổi gì. Mục đích là ngăn sự cố lặp lại, hơn là đổ lỗi.
C-state CPU idle state
Trạng thái tiết kiệm điện mà CPU đi vào khi rảnh. Trạng thái càng sâu càng tiết kiệm điện nhưng càng mất thời gian để thức dậy.
Live migration Live migration
Việc cloud chuyển một máy ảo đang chạy sang host khác, chẳng hạn để bảo trì host. Vào lúc chuyển, máy ảo có thể dừng trong chốc lát.
SNAT Source NAT
NAT đổi địa chỉ nguồn của gói tin đi ra thành địa chỉ công cộng. Một địa chỉ công cộng chỉ dùng được một số cổng có hạn, dùng hết thì kết nối mới thất bại.
NAT gateway NAT gateway
Thiết bị trên cloud cho các server trong mạng riêng dùng chung một địa chỉ công cộng khi ra Internet. Có giới hạn số kết nối đồng thời theo từng đích.
Internet vệ tinh quỹ đạo thấp LEO satellite internet
Internet kết nối qua các vệ tinh ở độ cao vài trăm đến vài nghìn km. Độ trễ ngắn hơn nhiều so với vệ tinh địa tĩnh, nhưng có thể vọt lên khi đổi vệ tinh đang kết nối.
GeoIP IP geolocation
Cơ sở dữ liệu ước đoán quốc gia, thành phố, nhà mạng từ địa chỉ IP. Có mục sai hoặc đã cũ nên đôi khi khiến người chơi bị xếp vào server ở khu vực xa.
Chứng chỉ TLS TLS certificate
Tài liệu điện tử chứng minh server đúng là server đó. Chứng chỉ có thời hạn; hết hạn thì kết nối mã hóa thất bại và không thể truy cập.
Tạo khung hình Frame generation
Công nghệ card đồ họa chèn khung hình dự đoán vào giữa các khung hình thật để tăng FPS. Màn hình mượt hơn nhưng độ trễ từ input đến màn hình có thể tăng.
T6Công cụ

Tài liệu tham khảo

Đây là căn cứ cho các con số, giá trị mặc định và mô tả hành vi trong sách trắng. Chỉ tập hợp tài liệu đáng tin cậy: tài liệu tiêu chuẩn (RFC), tài liệu kernel và OS, tài liệu chính thức về cloud, engine, DB, bài thuyết trình và bài báo khoa học. Thẻ nguyên nhân và mục “Nguồn” ở cuối mỗi chương cũng dẫn tới cùng các tài liệu này. Giá trị mặc định có thể đổi theo phiên bản, nên trước khi áp dụng thực tế, hãy xem tài liệu của phiên bản bạn đang dùng.

616 tài liệu từ 83 đơn vị phát hành. Danh sách đầy đủ nằm ở mục Tài liệu tham khảo của phiên bản văn bản.