遊戲 Lag 白皮書 › L8 Socket 與協定
慢速用戶端(slow consumer)的處理策略 Slow-consumer policy
原因 ID sk-slow-client · 主要負責 遊戲開發團隊(伺服器開發)
在含圖解與實驗的完整版中開啟卡片 →
對於待傳送資料不斷累積的用戶端,伺服器會丟棄過時的狀態更新,或直接切斷連線。
為什麼 用戶端的線路跟不上伺服器送出的資料量 → 於是 伺服器丟棄過時的狀態更新,或在超過上限時切斷連線 → 畫面上 只有那個人出現瞬移或斷線
- 症狀
- 瞬移, 斷線
- 因素
- 遺失
- 誰會遇到
- 只有我
- 何時
- 人潮湧入時
- 負責單位
- 主要負責 遊戲開發團隊(伺服器開發)
- 遊戲開發團隊要做的事
- 減少傳送量(依距離調整更新頻率)、降低品質但持續傳送、減少堆在 kernel 裡的資料量(Linux 的 TCP_NOTSENT_LOWAT)。
- 數值參考
- 傳送緩衝區為 256KB 時,在 30KB/s 的線路上會累積超過 8 秒的積壓資料。Linux 有時還會自動把這個緩衝區放大到數 MB。
- 圖表上
- 只有部分偏高 · 每條連線的 Send-Q、每個用戶端丟棄的狀態更新數
- 查看位置
- 看遊戲伺服器記錄的各用戶端傳送佇列長度、丟棄的狀態更新數與斷線原因,並在伺服器上用 ss -tni 一併確認該連線的 Send-Q 與 cwnd
- 符合的跡象
- 只有瞬移或斷線的人的連線 Send-Q 一直是滿的,遊戲 log 中記錄了該玩家的狀態更新遭丟棄,或因超過傳送佇列上限而斷線
- 不符合的跡象
- Send-Q 是空的卻仍瞬移時,問題不在伺服器傳送端。要查該玩家線路的封包遺失(「無線區段的封包遺失」)或畫面內插
- 確認方式
- 需要遊戲伺服器/用戶端的 log 與指標
出處
- IP Sysctl Linux kernel
tcp_wmem:自動調整的傳送緩衝區上限預設為 64KB~4MB(依記憶體而定);以 tcp_notsent_lowat、TCP_NOTSENT_LOWAT 限制尚未送出的資料量 - net/ipv4/tcp_diag.c (Linux v6.12) Linux kernel
ss 的 Recv-Q、Send-Q 值:listen socket 是等待 accept 的連線數與 backlog 上限;已連線的 socket 是應用程式尚未讀取的位元組數與尚未收到 ACK 的已送出位元組數
相關原因
同一層:L8 Socket 與協定
同一症狀(瞬移)在其他層的原因
查看含圖解與實驗的完整版卡片