遊戲 Lag 白皮書 › 依症狀查找
連不上/無限讀取:45 個原因與負責團隊
其他說法:登不進去、讀取跑不完
在含圖解的完整版症狀辭典中開啟 →
進不了遊戲,或是停在讀取、進場畫面。
一直出現「無法連線到伺服器」,選完角色後讀取條跑不完。
負責接受新連線的地方(伺服器的連線等待佇列、防火牆、登入伺服器、DB)滿了。維護剛結束時特別常見。
造成這個症狀的原因
L2 用戶端 OS 與裝置
- 安全軟體的封包檢查: 防毒軟體、防火牆檢查每一個封包時延遲會增加,太過頭還會把遊戲誤判為攻擊而封鎖。 (外部(外部))
L3 家用網路
L4 網際網路線路
- 國家/電信業者層級的 UDP 限制與封包檢測: 部分網路會封鎖特定 UDP 位址與 port,或限制 UDP 速度;封包檢測設備也會過濾掉無法辨識的協定。用 UDP 通訊的遊戲在這類網路上會連不上或經常斷線。 (外部(外部))
- DNS 故障與延遲: 負責把伺服器名稱轉成位址的 DNS 一旦變慢或失敗,就找不到登入伺服器與更新伺服器。 (外部(外部))
- DDoS 造成共用線路飽和: 針對遊戲公司,或同一網路上其他對象的大量攻擊,會塞滿共用的線路。 (基礎設施團隊(網路基礎設施))
- 電信業者共用 IP(CGNAT): 行動網路與部分電信業者讓多位用戶共用一個 IP,並在短時間內清除閒置連線的 NAT mapping。 (遊戲開發團隊(用戶端開發))
- 經由 VPN/遊戲加速器: 開啟 VPN 或遊戲加速器後,封包會經過該公司的中繼伺服器。中繼伺服器很遠或壅塞時,反而會變慢。 (外部(外部))
L5 資料中心網路設備
- 防火牆 session 表飽和: 防火牆會把放行的每條連線記錄在 session 表中追蹤。表一旦滿了,就無法接受新連線。 (基礎設施團隊(網路基礎設施))
- DDoS 防護導流與誤判: 為了擋下攻擊而把流量導向清洗中心時,路徑會變長,有時還會把正常使用者誤判為攻擊而封鎖。 (基礎設施團隊(網路基礎設施))
- 雲端 NAT 閘道的連線與 port 上限: 私有子網路中的伺服器對外(平台驗證、付款、外部 API)的連線,由 NAT 閘道轉換位址與 port 後送出。送往同一目的地的同時連線超過閘道的 port 上限時,新連線就會失敗。 (基礎設施團隊(網路基礎設施))
- 負載平衡器分配不均與健康檢查誤判: 連線全集中到一台伺服器,或持續把人送往已經掛掉的伺服器。 (基礎設施團隊(網路基礎設施))
- MTU 不一致(只有大封包消失): 中途區段的 MTU(一次能傳送的大小)變小,而大小超過的通知又被擋掉時,只有大封包會一直消失。 (基礎設施團隊(網路基礎設施))
L7 伺服器 OS(kernel)
- 連線等待佇列(backlog)溢位: 維護剛結束時數萬人同時連線,kernel 的連線等待佇列(backlog)會溢位,連線請求因此被丟棄。 (遊戲開發團隊(伺服器開發))
- 檔案描述子上限: 每個連線都需要一個檔案描述子(fd,OS 為開啟的檔案或 socket 指定的編號),而一個處理程序能開啟的 fd 數量有上限。 (基礎設施團隊(伺服器基礎設施))
- 伺服器 conntrack 表飽和: Linux 防火牆會把每條連線記錄在連線追蹤(conntrack)表中,這個表碰到上限時就會丟棄新封包。 (基礎設施團隊(伺服器基礎設施))
- 伺服器間連線的臨時 port 耗盡: 遊戲伺服器頻繁地對 DB 或其他伺服器建立又關閉短連線時,已關閉的連線會占用 port 一段時間,導致無法開啟新連線。 (遊戲開發團隊(伺服器開發))
L8 Socket 與協定
- keepalive 預設值 2 小時: 對方沒有送出關閉訊號就消失時,TCP 要過很久才會察覺。keepalive(確認閒置連線是否仍存活的 TCP 功能)預設是關閉的,即使開啟,也要閒置 2 小時才開始確認。 (遊戲開發團隊(伺服器開發))
- SO_REUSEPORT 分配不均: 多個處理程序共用同一個 port 接收時,kernel 會依位址雜湊為每個連線指定負責的處理程序,之後不再更換。其中一個處理程序停住時,只有分配給它的人要等待。 (遊戲開發團隊(伺服器開發))
L9 伺服器遊戲程式
- 執行緒池耗盡: 負責處理工作的工作執行緒全被慢的工作綁住時,新請求只能無止盡地等待。 (遊戲開發團隊(伺服器開發))
L11 磁碟
- 寫入 core dump: 伺服器當機時要把數 GB 的記憶體寫入磁碟,有時會讓重新啟動延後好幾分鐘。 (基礎設施團隊(伺服器基礎設施))
L12 資料庫
- 沒有索引的查詢: 沒有索引時,要找出符合條件的資料列,就必須讀完整張資料表(全表掃描)。 (遊戲開發團隊(伺服器開發))
- 連線池耗盡: 與 DB 建立的連線數是固定的,慢查詢占住連線時,其餘請求只能等待。 (遊戲開發團隊(伺服器開發))
- 冷快取(剛重新啟動時): DB 重新啟動後記憶體快取是空的,有一段時間所有查詢都要從磁碟讀取。 (基礎設施團隊(DB 基礎設施))
- 登入暴增與 N+1 查詢: 載入一個角色要分開查詢數十次的話,數萬人同時登入就會變成數百萬個查詢。 (遊戲開發團隊(伺服器開發))
- DB 容錯移轉: 主 DB 故障、切換到備援 DB 的期間無法寫入,最後一批還沒複寫過去的資料可能會遺失。 (基礎設施團隊(DB 基礎設施))
- Cache stampede: 熱門資料的快取同時過期時,數千個請求會一口氣湧向 DB。 (遊戲開發團隊(伺服器開發))
- Redis 慢指令: Redis 一次只處理一個指令,因此一個慢指令就會擋住後面所有的請求。 (遊戲開發團隊(伺服器開發))
- 執行計畫改變造成的查詢延遲: 程式碼沒變,DB 卻改變了處理同一個查詢的方式(執行計畫)時,昨天只要 2ms 的查詢,今天會變成數百 ms。 (基礎設施團隊(DB 基礎設施))
- 營運中 schema 變更(DDL)的鎖定: 在服務中替資料表新增欄位或索引時,可能因為一個只需要短暫持有的鎖定,讓所有使用該資料表的請求都在等待。 (基礎設施團隊(DB 基礎設施))
L13 伺服器架構與維運
- 切換 zone(跨伺服器轉移): 進入其他地圖或副本時,把角色資料交給另一台伺服器的過程中會產生延遲與失敗。 (遊戲開發團隊(伺服器開發))
- 連鎖故障: 一個服務變慢時,呼叫它的伺服器會卡在等待回應,連不相關的功能也跟著停擺。 (遊戲開發團隊(伺服器開發))
- 附屬伺服器故障: 聊天、隊伍、拍賣場這類與遊戲伺服器分開運作的伺服器故障時,只有那個功能無法運作。 (遊戲開發團隊(伺服器開發))
- 部署與重新啟動: 為了更新而重新啟動伺服器時,如果不先把連線移走,原本在那台伺服器上的人就會斷線,關閉前的存檔與重新連線也會同時湧入。 (遊戲開發團隊(伺服器開發))
- 自動擴展延遲: 人潮湧入時會自動增加伺服器,但準備要花幾分鐘,這段期間既有的伺服器處於過載。 (基礎設施團隊(伺服器基礎設施))
- 依賴外部服務: 平台登入、付款、身分驗證這類外部服務變慢或停擺時,會卡在那個步驟。 (外部(外部))
- TLS 憑證過期/設定錯誤: 登入、API、更新伺服器的憑證過期或缺少中繼憑證時,從那一刻起新連線的用戶端 TLS 連線都會失敗。 (基礎設施團隊(網路基礎設施))
- 登入排隊上限與重新連線寬限不足: 上市或維護剛結束時連線湧入,登入排隊碰到上限就拒絕新的排隊,正在排隊的玩家只要短暫斷線就會失去位置,回到隊伍最後面。 (遊戲開發團隊(伺服器開發))
同步設計
只有部分人遇到的問題
- 特定角色的資料過於龐大: 累積了數千個道具或信件,或好友、封鎖名單、buff 特別多的角色,在登入、儲存與通知周圍玩家時要處理的量是別人的好幾倍。與線路無關,只有用那個角色時才慢。 (遊戲開發團隊(伺服器開發))
- 固定 UDP port 衝突: 用戶端若設計成使用固定的本機 port,同一台電腦的第二個用戶端就無法使用該 port,或與第一個用戶端分食封包。 (遊戲開發團隊(用戶端開發))
- 多開限制: 安全模組或伺服器政策限制同一台電腦開多個用戶端時,第二個用戶端會無法執行或連線,或者先開的那一個會斷線。有些遊戲只封鎖額外用戶端的功能。 (遊戲開發團隊(用戶端開發))
TCP 重傳的根本原因
- 防火牆與連線追蹤丟棄封包: 防火牆或 Linux 連線追蹤(conntrack,把經過的連線記錄在表中的功能),在表已滿或判斷連線狀態不符時,會丟棄封包。 (基礎設施團隊(網路基礎設施))
- MTU 黑洞(只有大封包反覆遺失): 中途區段能接收的大小變小,而「封包太大」的通知(ICMP)又被擋掉時,大封包不管重送幾次都會一直消失。 (基礎設施團隊(網路基礎設施))
- 連線請求(SYN)重傳: 連線請求因連線等待佇列(backlog)溢位或被防火牆阻擋而消失時,用戶端 OS 會從 1 秒後開始,逐步拉長間隔重送。 (遊戲開發團隊(伺服器開發))
查看含圖解的完整版症狀辭典