한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

遊戲 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 期間無法使用),所以越常反覆建立短連線,越快碰到上限。

出處

  1. NAT gateway basics AWS
    每個 IPv4 位址對同一目的地(目的 IP、port、協定)5 萬 5 千條同時連線,最多掛 8 個 IP 擴充(公用 NAT 閘道的彈性 IP 預設 2 個,申請提高配額後可增加),頻寬從 5Gbps 自動擴充到 100Gbps、處理量從每秒 100 萬個封包自動擴充到 1,000 萬個,超過上限就丟棄
  2. NAT gateway metrics and dimensions AWS
    ErrorPortAllocation:無法分配來源 port 的次數(大於 0 表示同時連線過多),ActiveConnectionCount,IdleTimeoutCount(因閒置 350 秒而被清理的連線),PacketsDropCount
  3. Troubleshoot NAT gateways AWS
    閒置 350 秒後連線過期,之後繼續送出會收到 RST,建議 keepalive 間隔短於 350 秒,碰到連線上限時依可用區域增設閘道、增加 IP、減少連線數
  4. Source Network Address Translation (SNAT) with Azure NAT Gateway Microsoft Azure
    每個公用 IP 有 64,512 個 SNAT port(IP 最多 16 個),送往同一目的地的每條連線都需要不同的 port,已關閉的 port 再用於同一目的地之前有冷卻時間
  5. Metrics and alerts for Azure NAT Gateway Microsoft Azure
    以 Failed 狀態篩選的 SNAT Connection Count 大於 0 時,可能是 SNAT port 耗盡,Dropped Packets
  6. IP addresses and ports Google Cloud
    每個 NAT IP 的 TCP、UDP 各有 64,512 個 port,每個 VM 最少 port 數預設 64(靜態分配)、32(動態分配),VM 預留的 port 數限制了對同一目的地的同時連線數,已關閉的連線在 TIME_WAIT 期間無法使用
  7. Logs and metrics Google Cloud
    dropped_sent_packets_count 的 reason OUT_OF_RESOURCES:因 NAT IP 或 port 不足而丟棄的封包

相關原因

同一層:L5 資料中心網路設備

同一症狀(連不上/無限讀取)在其他層的原因

查看含圖解與實驗的完整版卡片