遊戲 Lag 白皮書 › L5 資料中心網路設備
雲端 NAT 閘道的連線與 port 上限 Cloud NAT gateway connection / port limits
原因 ID dc-nat-gateway · 主要負責 基礎設施團隊(網路基礎設施) · 協同 遊戲開發團隊(伺服器開發)
在含圖解與實驗的完整版中開啟卡片 →
私有子網路中的伺服器對外(平台驗證、付款、外部 API)的連線,由 NAT 閘道轉換位址與 port 後送出。送往同一目的地的同時連線超過閘道的 port 上限時,新連線就會失敗。
為什麼 伺服器對平台驗證、付款這類同一個外部位址大量開啟短連線,或長時間開著連線 → 於是 NAT 閘道無法再分配該目的地可用的來源 port,新連線失敗 → 畫面上 遊戲內一切正常,只有登入、付款、發放獎勵這類呼叫外部的功能失敗或變慢(連不上/無限讀取、吃指令/回檔)
症狀 連不上/無限讀取 , 吃指令/回檔
因素 遺失, 延遲
誰會遇到 只有特定功能, 整個伺服器
何時 剛登入/維護剛結束, 晚間尖峰時段, 人潮湧入時
負責單位 主要負責 基礎設施團隊(網路基礎設施) · 協同 遊戲開發團隊(伺服器開發)
遊戲開發團隊要做的事 外部 API 要重複使用連線(HTTP keep-alive、連線池),不要每次請求都開新連線;留在池中的閒置連線,要以比 NAT 閒置逾時(AWS 350 秒)更短的間隔送出 keepalive,或先行關閉;失敗時逐步拉長重試間隔並隨機分散;記錄各外部呼叫的失敗率與延遲。
基礎設施團隊要做的事 為 NAT 閘道增加 IP 位址(AWS 公用 NAT 閘道預設只能掛 2 個彈性 IP,超過需申請提高配額);依可用區域、子網路拆分閘道;為 port 分配失敗指標(AWS ErrorPortAllocation、Azure SNAT Connection Count 的 Failed、Google Cloud dropped_sent_packets_count 的 OUT_OF_RESOURCES)設定警示;Google Cloud NAT 可提高每個 VM 的最少 port 數,或改用動態 port 分配。
數值參考 AWS NAT 閘道每個 IP 位址對同一目的地(IP、port、協定)最多可開 5 萬 5 千條同時連線,最多可掛 8 個 IP 來擴充。350 秒沒有流量的連線會被清除,之後再從這條連線送出的封包會收到 RST。Azure NAT Gateway 每個公用 IP 有 64,512 個 SNAT port(IP 最多 16 個)。Google Cloud NAT 把每個 NAT IP 的 64,512 個 port 分給各 VM,但每個 VM 的最少 port 數預設為 64 個(靜態分配),所以預設設定下,一台 VM 對同一目的地能同時開的連線通常被限制在 64 條。
圖表上 碰到上限後持平 · NAT 閘道同時連線數、port 分配失敗數
查看位置 AWS 查看 CloudWatch 中的 NAT 閘道指標 ErrorPortAllocation、ActiveConnectionCount、PacketsDropCount(Azure 為以 Failed 狀態篩選的 SNAT Connection Count 與 Dropped Packets,Google Cloud 為 dropped_sent_packets_count 中 reason 為 OUT_OF_RESOURCES 的值),與遊戲伺服器外部呼叫失敗的時間點並排比對 符合的跡象 外部呼叫失敗的時間點 ErrorPortAllocation(Azure 為 Failed 狀態的 SNAT Connection Count,Google Cloud 為 OUT_OF_RESOURCES 丟棄)大於 0,失敗集中在驗證、付款伺服器這類連線大量集中的一兩個目的地 不符合的跡象 port 分配失敗為 0,但遊戲伺服器的 connect 以 EADDRNOTAVAIL 失敗、TIME_WAIT 數接近臨時 port 範圍時,是「伺服器間連線的臨時 port 耗盡」。能連上但只有回應很慢時,是「依賴外部服務」 確認方式 用基礎設施工具確認(不需要遊戲程式碼)
深入了解 與單台伺服器的臨時 port 用完的「伺服器間連線的臨時 port 耗盡」不同,這個上限卡在 NAT 閘道上,由閘道後方的伺服器共用(Google Cloud NAT 則分給各 VM)。伺服器端的 TIME_WAIT 與臨時 port 範圍都還有餘裕,卻只有外部呼叫失敗時,就是這個原因。已關閉連線的 port 也不會立刻再用於同一目的地(Azure 有冷卻時間,Google Cloud 在 TIME_WAIT 期間無法使用),所以越常反覆建立短連線,越快碰到上限。
出處 NAT gateway basics AWS 每個 IPv4 位址對同一目的地(目的 IP、port、協定)5 萬 5 千條同時連線,最多掛 8 個 IP 擴充(公用 NAT 閘道的彈性 IP 預設 2 個,申請提高配額後可增加),頻寬從 5Gbps 自動擴充到 100Gbps、處理量從每秒 100 萬個封包自動擴充到 1,000 萬個,超過上限就丟棄 NAT gateway metrics and dimensions AWS ErrorPortAllocation:無法分配來源 port 的次數(大於 0 表示同時連線過多),ActiveConnectionCount,IdleTimeoutCount(因閒置 350 秒而被清理的連線),PacketsDropCount Troubleshoot NAT gateways AWS 閒置 350 秒後連線過期,之後繼續送出會收到 RST,建議 keepalive 間隔短於 350 秒,碰到連線上限時依可用區域增設閘道、增加 IP、減少連線數 Source Network Address Translation (SNAT) with Azure NAT Gateway Microsoft Azure 每個公用 IP 有 64,512 個 SNAT port(IP 最多 16 個),送往同一目的地的每條連線都需要不同的 port,已關閉的 port 再用於同一目的地之前有冷卻時間 Metrics and alerts for Azure NAT Gateway Microsoft Azure 以 Failed 狀態篩選的 SNAT Connection Count 大於 0 時,可能是 SNAT port 耗盡,Dropped Packets IP addresses and ports Google Cloud 每個 NAT IP 的 TCP、UDP 各有 64,512 個 port,每個 VM 最少 port 數預設 64(靜態分配)、32(動態分配),VM 預留的 port 數限制了對同一目的地的同時連線數,已關閉的連線在 TIME_WAIT 期間無法使用 Logs and metrics Google Cloud dropped_sent_packets_count 的 reason OUT_OF_RESOURCES:因 NAT IP 或 port 不足而丟棄的封包
相關原因
同一層:L5 資料中心網路設備
同一症狀(連不上/無限讀取)在其他層的原因
查看含圖解與實驗的完整版卡片