遊戲 Lag 白皮書 › 依症狀查找
快轉:36 個原因與負責團隊
其他說法:唰唰唰、像按了快轉、一口氣全部處理完
在含圖解的完整版症狀辭典中開啟 →
停住的畫面重新動起來時,積壓的移動、打擊和傷害一口氣快速跑完。
怪物和玩家像快轉一樣移動,傷害數字與特效一次全部噴出來。
封包在某處堆積,然後一次放行。典型的例子是 TCP 等待重傳、伺服器追進度、用戶端處理積壓。
造成這個症狀的原因
L1 用戶端遊戲程式
- 主執行緒封包處理瓶頸: 每個畫格只處理固定數量的已接收封包時,一次湧入的封包會不斷延到下一個畫格。 (遊戲開發團隊(用戶端開發))
- 固定時間步長追趕失控: 停過一次之後集中補算落後的部分,又因為這些計算而再度落後。 (遊戲開發團隊(用戶端開發))
L2 用戶端 OS 與裝置
- 背景處理程序占用 CPU: 防毒掃描、Windows Update、直播軟體、瀏覽器影片占住 CPU 核心時,遊戲執行緒分配不到 CPU,只能等待。 (外部(外部))
- 接收緩衝區溢位: 遊戲太忙,太晚從 socket(OS 提供的網路收送介面)取出封包時,OS 緩衝區就會溢位。 (遊戲開發團隊(用戶端開發))
- 同一台裝置上的其他 App 占用頻寬: 雲端同步、大型下載、遊戲更新在同一台電腦上執行時,遊戲封包得在佇列中等待。 (外部(外部))
- 視窗最小化或非作用中時的處理限制: 切到其他視窗或把遊戲最小化時,遊戲與 Windows 會為了省電讓遊戲跑得比較慢。回到遊戲時,累積的封包會一口氣湧入,或者早已斷線。 (遊戲開發團隊(用戶端開發))
L3 家用網路
L6 伺服器網路卡
- 雲端主機維護與即時遷移: 雲端供應商維護實體伺服器(主機)時,會把虛擬機器搬到其他主機(即時遷移),或暫時停住。這段期間整台伺服器都會停住,停住的時間一長,連線就會中斷。 (基礎設施團隊(伺服器基礎設施))
L7 伺服器 OS(kernel)
L8 Socket 與協定
- TCP HOL 阻塞: TCP 為了維持順序,在重新收到遺失的那一個封包之前,不會把之後到達的封包交給遊戲。 (遊戲開發團隊(伺服器開發))
- 可靠 UDP 的重傳設定: 在 UDP 上自行實作的重傳規則太保守時復原會變慢,太積極時反而讓線路更壅塞。 (遊戲開發團隊(伺服器開發))
- 壅塞控制造成傳送量驟降: TCP 把封包遺失視為壅塞的訊號,會把傳送速率降低 30~50%。對 Wi-Fi 造成的遺失也會做出同樣的反應。 (基礎設施團隊(伺服器基礎設施))
L9 伺服器遊戲程式
- 廣播量暴增: 把一個人的移動送給所有看得到他的人時,要送出的狀態更新數量會是聚集人數的平方。 (遊戲開發團隊(伺服器開發))
- 集中在單一目標的戰鬥(世界王): 數百人同時攻擊同一隻王時,這隻王的運算全集中在一處,打擊資訊也要傳送給所有看得到的人。 (遊戲開發團隊(伺服器開發))
- 進入密集區域時的生成暴增: 用傳送移動到擠滿人的城鎮時,伺服器必須一次送出數百位新進入視野者的外觀、裝備與狀態。 (遊戲開發團隊(伺服器開發))
L10 記憶體
- 伺服器 GC 全面暫停: Java、C# 伺服器為了回收垃圾而暫停所有執行緒(stop-the-world)的期間,整個伺服器都會停住。 (遊戲開發團隊(伺服器開發))
同步設計
- 沒有時間戳記、一到就播放: 伺服器事件沒有附上發生時間、一收到就播放時,網路抖動會讓演出時機跟著忽快忽慢。 (遊戲開發團隊(用戶端開發))
只有部分人遇到的問題
- 慢的人在別人畫面上快轉移動: 線路差的人,輸入會忽快忽慢、成批抵達伺服器。伺服器每個 tick 收到多少就套用多少時,在其他人眼中,那個角色會頓一下後一次走好幾步。 (遊戲開發團隊(伺服器開發))
- 一到就處理的伺服器造成快轉: 封包一抵達就立即處理並通知的伺服器,會把慢的人成批湧入的動作接連立即執行。 (遊戲開發團隊(伺服器開發))
- 怪物控制權在慢速用戶端上: 有些遊戲為了減輕伺服器負載,把怪物移動的計算交給附近某位玩家的用戶端。那個人線路差時,該怪物在所有人的畫面上都會動得很怪。 (遊戲開發團隊(伺服器開發))
- 背景視窗的處理限制: 背景視窗中的用戶端,會被遊戲、引擎、OS 降低畫格數與處理量。收到的封包來不及處理,就會積壓或溢位。 (遊戲開發團隊(用戶端開發))
TCP 重傳的根本原因
- 無線區段的封包遺失: Wi-Fi 與行動網路在無線區段會先重傳幾次,仍然失敗就丟棄封包。被丟棄的封包,TCP 要過好一段時間才會重送。 (外部(外部))
- 瓶頸佇列溢位(壅塞遺失): 分享器、電信業者之間的互連區段、資料中心線路這類最窄的地方,佇列一滿就會丟棄新進來的封包。 (基礎設施團隊(網路基礎設施))
- 突發傳送造成淺緩衝區溢位: 伺服器每個 tick 把數千人份的更新在一瞬間集中送出時,交換器的小緩衝區或雲端的瞬間上限不到 1ms 就會溢位,部分封包因此被丟棄。 (遊戲開發團隊(伺服器開發))
- Policer 丟棄超額流量: 電信業者的資費方案、雲端執行個體的上限、DDoS 防護設備,有時會把超過規定速度的封包直接丟棄,不放進佇列。 (基礎設施團隊(網路基礎設施))
- 實體層錯誤(線材、光模組、接頭不良): 纜線損壞、沾了灰塵的光纖接頭、壽命將盡的光模組會造成位元錯誤,損壞的封包會被設備默默丟棄。 (基礎設施團隊(網路基礎設施))
- 雙工模式不一致: 一端設為自動協商、另一端把速度與雙工固定時,其中一端會以半雙工運作,每當負載升高就因碰撞而遺失封包。 (基礎設施團隊(網路基礎設施))
- 接收端伺服器主機丟棄封包: 封包已經到了伺服器,卻因 NIC 的 ring buffer(暫存剛抵達封包的緩衝區)溢位,或 kernel 負責接收處理的 CPU 核心滿載而被丟棄。 (基礎設施團隊(伺服器基礎設施))
- 中間設備超過處理上限(防火牆、IPS、DDoS 防護): 防火牆、入侵防禦設備(IPS)、DDoS 防護設備會逐一檢查經過的封包。從超過檢查能力的那一刻起,處理不了的封包就會被丟棄。 (基礎設施團隊(網路基礎設施))
- 路由變更、ECMP 不良路徑: 網際網路路由變更的那幾秒內,或是多條 ECMP 路徑中被分配到不良路徑的連線,會有封包消失。 (基礎設施團隊(網路基礎設施))
- 延遲飆升造成的不必要重傳: 封包沒有消失,只是短暫地很晚才到;但這段延遲比 RTO 長時,傳送端就會判斷為遺失而重傳。 (外部(外部))
- RTO 設定不符合環境: RTO 最小值調得太低時,只要稍微延遲就會產生不必要的重傳;預設值(200ms)對遊戲來說又太長,每遺失一次就要停住很久。 (基礎設施團隊(伺服器基礎設施))
- thin stream 復原緩慢: 像遊戲這樣零星送出小封包時,在湊齊「後續 3 個封包」之前 RTO 就先到了。同樣的遺失,停住的時間比大量傳輸長得多。 (遊戲開發團隊(伺服器開發))
- 中間設備移除 TCP 選項: 部分防火牆或加速設備刪除或改寫 TCP 選項時,遺失多個封包後一個往返只能復原一個,或是視窗(一次可送出的量)變小,傳輸因此變慢。 (基礎設施團隊(網路基礎設施))
- Zero window(看起來像重傳的停頓): 接收端程式沒有及時讀取 socket、緩衝區塞滿時,傳送端會停止傳送,只送出 zero window probe。線路本身沒有問題。 (遊戲開發團隊(用戶端開發))
查看含圖解的完整版症狀辭典