阿里雲帳號認證服務 阿裡雲 NAT 網關(SNAT/DNAT)導致內網 ECS 訪問外網卡頓或連線數打滿
問題現象:不是所有卡頓都來自帶寬
很多團隊在阿里雲上遇到一種很典型的現象:內網 ECS 明明還有 CPU、記憶體和磁碟空間,業務卻在訪問外網時突然變慢,甚至出現連線建立失敗、請求超時、偶發重試暴增。表面看起來像是應用性能問題,實際上根因常常落在 NAT 網關上,尤其是 SNAT 連線數打滿、埠位資源緊張,或者 DNAT 規則與回程路徑設計不合理。
這類問題最麻煩的地方在於,它不是單點故障,而是逐步惡化。前期只是偶爾卡頓,到了高峰期就會變成大面積超時;有時候短時間恢復正常,過一陣子又復發。若沒有把 NAT 網關納入排查視角,很容易在應用、資料庫、DNS、甚至容器網路上兜圈子,最後錯過真正的瓶頸。
NAT 網關到底在忙什麼
阿里雲帳號認證服務 先把概念講清楚。SNAT 的作用,是讓內網 ECS 透過 NAT 網關主動訪問外網時,對外呈現為某個或某組公網 IP。DNAT 的作用,則是把外部流量轉發到內部 ECS 的指定端口或服務。前者解決「出去」的問題,後者解決「進來」的問題。看起來只是地址轉換,但實際上 NAT 網關同時承擔了狀態維護、五元組映射、埠位分配、連線老化與轉發處理。
一旦業務量上升,NAT 網關承受的不只是帶寬,還包括大量短連線、長連線、突發重試和錯誤回收。對於 HTTP API、爬蟲、消息推送、外部支付回調、第三方接口對接這類場景,SNAT 壓力尤其明顯。因為這些業務往往有一個共同特點:單位時間內新建連線很多,且目的地址分散,容易迅速消耗 NAT 網關的連線追蹤和可用埠位。
常見成因:卡頓背後的四個關鍵點
1. SNAT 連線數和埠位耗盡
這是最常見的根因。每一條內網出網連線,經過 NAT 網關後都需要映射到對外的地址與埠。當同一個 SNAT 地址下的連線數過多,或者短時間內建立和釋放連線的頻率太高,就可能把可用埠位和連線跟蹤表推到上限。這時新連線無法順利建立,表現出來就是偶發超時、握手慢、重試增加,嚴重時整體業務卡住。
很多人第一反應是擴大帶寬,但 NAT 壓力不等於純帶寬壓力。假如你只是把大流量影片、下載或 API 請求都壓在少數幾個 SNAT IP 上,帶寬可能還沒滿,連線表卻先爆了。真正卡住的不是「能不能傳」,而是「能不能建立新的映射」。
2. 長連線過多,老舊連線不釋放
有些業務會使用長連線、連線池或大量 keep-alive。這本身沒有問題,但如果連線池配置不合理,閒置連線長期不回收,NAT 網關上的狀態表就會堆積。更糟的是,某些客戶端和代理組合會保留半開連線,讓 NAT 狀態持續占用資源。結果就是看似流量不大,連線表卻一直高位運行。
這種情況特別容易誤判。因為應用層沒有明顯錯誤,服務也還活著,只是偶爾慢半拍。但如果去看 NAT 網關相關監控,就會發現連線數、端口使用率、丟棄次數或者新建失敗數都在上升。
3. 回程路徑不一致,導致連線抖動
DNAT 場景下,最容易出現的是回程路由不對稱。也就是流量進來經過了 NAT 網關,但回去的路徑卻從別的出口走了,導致會話狀態無法正確匹配。這種問題表面看起來像「偶發超時」,實際上是轉發鏈路前後不一致。若同時存在多個出口、EIP、SLB、路由表或安全組策略,排查難度會更高。
對於需要對外提供服務的 ECS,如果 DNAT、ECS 路由、內部網段劃分和安全策略沒有一起設計,流量在不同設備之間來回跳轉,就可能產生重傳、丟包或握手不完整。這類問題不一定一直發生,但一旦發生,體感往往就是「很卡,而且很難復現」。
4. 上游第三方限制與重試風暴
還有一類情況並不是 NAT 本身壞了,而是外部服務端限制了來源 IP 的並發、頻率或端口使用。當 ECS 集中經過少量 SNAT IP 對外訪問時,第三方會把這些請求看成來自同一出口。如果外部接口限流,應用就會持續重試;重試一多,NAT 連線就更緊張,最後形成惡性循環。這也是為什麼很多故障一開始只是第三方接口慢,最後卻演變成整個出口都卡。
阿里雲帳號認證服務 排查思路:先看現象,再找瓶頸
遇到這類問題,不要急著改參數,應該先把鏈路拆開看。第一步是確認問題是否只發生在出網請求上。如果內網訪問內網正常,只有訪問外部 API、下載、註冊、回調等動作慢,那 NAT 的嫌疑就非常大。第二步是觀察故障期間 NAT 網關的監控指標,重點看新建連線數、活躍連線數、丟棄包、SNAT 埠位使用率、DNAT 轉發量和帶寬峰值。
第三步是回到 ECS 本身看系統層表現。若大量進程卡在 connect、SYN_SENT、TIME_WAIT 或 CLOSE_WAIT,就能判斷問題和連線生命周期有關。若應用層重試驟增、超時比例升高,而 upstream 的 RTT 正常,那更像是 NAT 層資源吃緊。第四步是檢查安全組、路由表和是否存在多出口。只要路由不對稱,很多看似隨機的故障其實都能解釋得通。
如果條件允許,最好在故障窗口做一次壓測或對照測試。用少量流量模擬真實請求,逐步提高並發,看 NAT 指標是先於應用出現異常,還是應用先出現錯誤。這個順序很重要。只要能證明 NAT 是先壞的,定位就會清晰很多。
真正有效的優化,不是單純加機器
1. 分散 SNAT 壓力
如果所有 ECS 都共用少量 SNAT 公網 IP,連線壓力會集中在同一個出口上。更穩妥的做法,是按業務、環境或用途拆分出口,讓不同類型的流量走不同的 SNAT 地址。這樣不僅能降低單個 IP 的端口壓力,也能把故障面縮小。對高並發業務來說,這通常比盲目擴容更有效。
2. 減少短連線和無效重試
能複用連線就不要頻繁新建。把 HTTP 客戶端、資料庫客戶端、消息推送和第三方 SDK 的連線池調好,能明顯降低 NAT 映射壓力。對失敗重試也要設計節流機制,避免一次外部抖動觸發全站重試。很多 NAT 爆表事故,其實不是正常流量造成的,而是重試風暴把問題放大了。
3. 清理閒置與異常連線
調整超時時間、心跳機制和連線回收策略,讓失效連線更快釋放。對於有代理層的架構,還要檢查代理和後端之間是不是保留了過多閒置連線。只要有一層不釋放,NAT 狀態表就會被悄悄占滿。這類問題平時不容易感知,但在高峰時會很致命。
4. 讓路由和轉發保持一致
DNAT 場景下,務必確保入站、回程和安全策略是一套完整設計,而不是臨時拼湊。外部流量如果經由 NAT 網關轉進 ECS,就要確認回包也能按預期路徑出去,避免多出口、多跳轉發和非對稱路由。對需要長連線的服務,這一點尤其重要,因為任何回程抖動都會放大成客戶可感知的延遲。
5. 給峰值留足餘量
NAT 問題往往不是在平均流量下暴露,而是在峰值、活動、批量任務、定時同步或外部故障恢復時集中爆發。所以設計容量時不能只看日常平均值,而要按高峰並發、突發重試和失敗回復後的流量疊加來預留。對 NAT 網關來說,餘量不是奢侈品,而是穩定性的保險絲。
實戰經驗:哪些信號最值得盯
如果你只能盯少數幾個信號,優先看這些:一是出網請求的超時率是否與 NAT 指標同步上升;二是新建連線速度是否下降;三是短時間內重試次數是否異常增加;四是某個 SNAT IP 是否明顯比其他地址更忙;五是故障是否只在特定時段、特定業務、特定出口出現。這些信號一旦同時出現,基本就可以把 NAT 網關列為第一嫌疑人。
另外,不要忽視看似無關的變化,比如最近是否上線了新服務、是否把多個系統共用到同一個出口、是否新增了批量任務、是否切換了連線庫版本。很多 NAT 故障並不是基礎設施突然變差,而是業務演進後把原本夠用的出口資源慢慢吃光了。
結語:把 NAT 當成核心基礎設施來管理
對很多團隊來說,NAT 網關常被當成「默默工作」的背景角色,出了問題才想起它。但只要業務有大量外網訪問,NAT 就不只是轉發設備,而是整個出網架構的關鍵瓶頸。SNAT 解決的是並發出口,DNAT 解決的是入站分流,兩者都不只是配置一條規則那麼簡單,而是要和連線池、重試策略、路由設計、監控告警一起看。
如果內網 ECS 訪問外網經常卡頓,先別急著懷疑應用寫壞了。先看 NAT 網關的連線、端口、路由和重試行為,往往更快找到真相。把 NAT 問題前置管理,很多原本會在凌晨爆發的故障,都能提前消化在設計和監控階段。這才是讓系統穩下來的真正方法。

