】应用服务中的SNAT (Source Network Address Translation 源网络地址转化) 1: SNAT 是怎么工作的以 TCP 连接为例一次出站访问大致是这样发生的image负载均衡器会维护一条映射记录例如字段 示例协议 TCPWorker 实例地址 10.0.5.60:51014负载均衡器公网地址 13.76.245.72:12481外部服务地址 52.189.232.180:80注意应用看到的是自己连到了外部服务外部服务看到的是负载均衡器的公网地址负载均衡器负责在两边之间做地址转换这个过程对应用和外部服务都是透明的2: SNAT 端口耗尽SNAT 端口的消耗和 TCP 五元组有关字段 含义Protocol 协议例如 TCPSource IP 源 IPSNAT 后是负载均衡器公网 IPSource Port 源端口也就是 SNAT 端口Destination IP 外部目标 IPDestination Port 外部目标端口注意如果多个 TCP 流访问的是同一个目标 IP、同一个目标端口、同一个协议那么它们需要不同的源端口来区分。也就是说高并发访问同一个外部服务时SNAT 端口会很快被消耗。反过来如果多个流访问的是不同目标 IP 或不同端口那么五元组本身已经不同SNAT 端口就有机会被复用。每个 IP 地址最多只能打开有限数量的端口。如果应用频繁打开和关闭连接情况会更严重。因为 SNAT 端口关闭后不会马上释放关闭方式 SNAT 端口释放时间正常 FIN/ACK 关闭 约 240 秒后释放RST 重置 约 15 秒后释放达到 idle timeout 按 idle timeout 释放这意味着如果一个 Web 应用每秒打开 1 条 HTTP 连接调用后端服务后正常关闭那么在 240 秒内可能累计占用约 240 个 SNAT 端口。另一个例子是数据库连接池如果一个繁忙站点的 SQL 连接池大小是 300并且数据库查询执行较慢那么这些连接可能持续占用约 300 个 SNAT 端口。还有一种常见情况是队列触发的 Function App如果压测一开始就把大量消息一次性灌入队列Function 可能瞬间启动大量到 Storage 或其他外部服务的连接很快耗尽 SNAT 端口。3: SNAT 端口分配算法为了避免某个站点耗尽整个 stamp 的 SNAT 端口并影响其他站点Azure Load Balancer 需要对 SNAT 端口做分配控制。常见算法包括分配方式 端口数量On-demand 算法 每实例基础 160 个可按需尽力分配更多新算法 每实例固定预分配 128 个这里的 160 个 SNAT 端口 可以用一个粗略的容量分摊思路来理解。一个典型的 App Service stamp 可能有 5 个出站 IP每个 IP 理论上有大约 65536 个端口。如果这些端口要被 stamp 内大约 2000 个实例共享那么每个实例能稳定分到的端口数量大约是5 × 65536 ÷ 2000 ≈ 163.84 取整后就接近 160 个端口 / 实例。4: SNAT 端口耗尽时的症状当 SNAT 端口耗尽时应用常见表现包括连接外部 endpoint 变慢请求长时间 pending最终出现 socket timeoutApplication Insights 里能看到依赖调用失败。如果启用了 Application Insights dependency tracking也可能看到外部依赖调用失败。5: 如何解决 App Service 的 SNAT 端口耗尽总体方向是先减少不必要的连接占用再考虑扩展。image具体建议复用连接不要每次请求都 new 一个 HttpClient使用连接池数据库、HTTP 客户端都应合理复用连接控制连接池大小连接池不是越大越好过大的池会持续占用端口降低重试强度失败时疯狂重试会进一步放大端口占用让后端尽快响应后端越慢连接存活越久SNAT 端口占用越久横向扩容 App Service PlanSNAT 端口按实例分配实例变多总可用端口也会增加使用 App Service EnvironmentASE 的实例池更小worker 实例通常可以获得更多 SNAT 端口压测要贴近真实流量负载测试应以稳定速度投喂数据而不是一开始就把所有消息一次性灌入队列。示例代码及优化下面的代码可以复现 SNAT 端口耗尽问题复制代码public string Index(string url){var request HttpWebRequest.Create(url);request.GetResponse();return OK;}复制代码为了复用连接可以改成关闭响应对象复制代码public string Fin(string url){var request HttpWebRequest.Create(url);var response request.GetResponse();response.Close();return OK;}复制代码下面这种写法也会造成 SNAT 端口泄漏因为每次调用都会创建新的 HttpClient复制代码public async Task Client(string url){using (var client new HttpClient()){await client.GetAsync(url);}return OK;}复制代码可以改成复用同一个 HttpClient复制代码private static Lazy _client new Lazy();public async Task ReuseClient(string url){var client _client.Value;await client.GetAsync(url);return “OK”;}复制代码常见问题FAQQ我能自己看到 App Service 的 SNAT 端口分配指标吗A一般情况下这个指标不直接公开。日常设计时不要依赖“实际能拿到多少端口”而应按每实例 128 个的保守值来控制。Q为什么不能直接根据 SNAT 端口指标做自动扩缩容A因为很多 SNAT 问题本质是连接没有复用。如果代码持续浪费连接单纯扩容只是把问题摊开并不一定治本。应该先优化连接复用和后端响应再考虑扩容。QSNAT 耗尽和 TCP Connections 耗尽有什么区别ATCP Connections 是 worker 实例层面的连接计数SNAT 是出站负载均衡器上的公网源端口资源。前者统计所有 TCP 连接后者只和外部网络流量有关。二者有关联但不能互相替代。Q多个 WebJob 共用同一个 App Service Plan怎么判断谁占用了最多连接A如果没有按进程维度的连接指标可以把部分 WebJob 移到另一个 App Service Plan通过隔离法观察问题是否缓解逐步定位高连接消耗的任务。

相关新闻

最新新闻

Poppins字体革命:免费开源的多语言几何字体终极指南

Poppins字体革命:免费开源的多语言几何字体终极指南

Poppins字体革命:免费开源的多语言几何字体终极指南 【免费下载链接】Poppins Poppins, a Devanagari Latin family for Google Fonts. 项目地址: https://gitcode.com/gh_mirrors/po/Poppins 🎯 价值主张:为什么Poppins是跨语言设计…

2026/7/11 10:01:10
Unity粒子特效进阶:Texture Sheet Animation原理与实战应用

Unity粒子特效进阶:Texture Sheet Animation原理与实战应用

1. 项目概述:为什么你需要精通Texture Sheet Animation? 在Unity里做特效,粒子系统是绕不开的核心工具。但很多开发者,尤其是刚入行的朋友,常常止步于调整颜色、大小、速度这些基础参数,对于粒子系统里那个…

2026/7/11 10:01:10
【RT-DETR涨点改进】23 RT-DETR 的 C++ 推理引擎实战:从 ONNX 到 TensorRT 的完整加速链路

【RT-DETR涨点改进】23 RT-DETR 的 C++ 推理引擎实战:从 ONNX 到 TensorRT 的完整加速链路

23 RT-DETR 的 C++ 推理引擎实战:从 ONNX 到 TensorRT 的完整加速链路 上篇我们聊了C++推理优化的底层思维,把延迟从47ms压到22ms。但坦白说,那只是“单步优化”。 如果你现在去生产环境跑一下,大概率会遇到一个尴尬场景:模型在Python里跑得飞起,一换C++就崩,或者精度…

2026/7/11 10:01:10
3种NAND Flash ECC方案对比:汉明码 vs BCH vs LDPC,纠错能力与开销实测

3种NAND Flash ECC方案对比:汉明码 vs BCH vs LDPC,纠错能力与开销实测

NAND Flash ECC技术深度解析:从汉明码到LDPC的实战演进 在数据存储的世界里,可靠性从来不是可选项而是必选项。想象一下,当你按下保存按钮时,那些看似普通的0和1正穿越NAND Flash芯片中数以亿计的存储单元,而其中任何一…

2026/7/11 10:01:10
为什么你的批量请求总在第97次失败?DeepSeek API并发限制的隐藏规则、埋点日志与自适应退避公式

为什么你的批量请求总在第97次失败?DeepSeek API并发限制的隐藏规则、埋点日志与自适应退避公式

更多请点击: https://kaifayun.com 第一章:为什么你的批量请求总在第97次失败? 这并非巧合,而是典型的“边界条件击穿”现象。当服务端配置了连接池上限、令牌桶速率限制或数据库连接数硬限(如 PostgreSQL 的 max_c…

2026/7/11 10:01:10
Haar小波变换图像压缩实战:Python/OpenCV 3步实现,PSNR 35dB+

Haar小波变换图像压缩实战:Python/OpenCV 3步实现,PSNR 35dB+

Haar小波变换图像压缩实战:Python/OpenCV 3步实现35dB高质量压缩 当我们需要在有限存储空间保存高分辨率图像时,图像压缩技术显得尤为重要。传统JPEG压缩在较高压缩比时会出现明显的块状伪影,而基于Haar小波变换的压缩方法能更好地保留图像边…

2026/7/11 9:56:09

月新闻