Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
本文帮助你排查 Azure 应用服务中的间歇性连接错误和相关性能问题。 它提供有关源网络地址转换 (SNAT) 端口耗尽的详细信息及其故障排除方法。 如果在本文中的任何时刻需要更多帮助,请联系 Azure 社区支持处的 Azure 专家。 或者,也可以提出 Azure 支持事件。 转到 Azure 支持,然后选择 提交支持请求。
在 Azure 应用服务上托管的应用程序和函数可能会显示以下一个或多个问题:
- 服务计划中的所有或部分实例的响应速度缓慢。
- 间歇性 5xx 错误或“错误的网关”错误。
- 超时错误消息。
- 无法连接到外部终结点(如 SQLDB、Service Fabric 或其他应用服务)。
出现间歇性连接问题的主要原因是在建立新的出站连接时遇到了限制。 可能遇到的限制包括:
- TCP 连接:可以建立的出站连接数有限制。 对出站连接的限制与使用的工作器大小有关。
- SNAT 端口数:Azure 中的出站连接介绍了 SNAT 端口限制以及它们对出站连接的影响。 Azure 使用源网络地址转换 (SNAT) 和负载均衡器(位向客户公开)与公共 IP 地址通信。 最初为 Azure 应用服务中的每个实例预分配了 128 个 SNAT 端口。 SNAT 端口限制会影响与同一个地址/端口组合打开的连接数。 如果应用与混合的地址/端口组合建立了连接,则不会用尽 SNAT 端口。 重复调用同一个地址/端口组合时,会用尽 SNAT 端口。 发布端口后,可根据需要重复使用该端口。 只有在等待四分钟后,Azure 网络负载均衡器才会从关闭的连接中回收 SNAT 端口。
当应用程序或功能快速打开新连接时,它们可以快速耗尽其 128 个端口的预分配配额。 然后,应用程序或功能会一直受到阻止,直到通过动态分配更多的 SNAT 端口或者通过重复使用回收的 SNAT 端口提供了新的 SNAT 端口为止。 如果应用耗尽了 SNAT 端口,将出现间歇性的出站连接问题。
有一些解决方案可以避免 SNAT 端口限制。 它们包括:
- 连接池:利用连接池,可以避免为对同一地址和端口的调用而打开新的网络连接。
- 服务终结点:对使用服务终结点保护的服务没有 SNAT 端口限制。
- 专用终结点:对使用专用终结点保护的服务没有 SNAT 端口限制。
- NAT 网关:使用 NAT 网关时,你会得到 64,000 个出站 SNAT 端口,通过该网关发送流量的资源可以使用这些端口。
为了避免 SNAT 端口问题,请避免对同一主机和端口反复创建新连接。 连接池是解决该问题更简单明了的方法之一。
如果目标是支持服务终结点的 Azure 服务,则可以通过使用 区域虚拟网络集成 和服务终结点或专用终结点来避免 SNAT 端口耗尽问题。 使用区域虚拟网络集成并在集成子网上放置服务终结点时,应用对这些服务的出站流量不会有出站 SNAT 端口限制。 同样,如果使用区域虚拟网络集成和专用终结点,则不会有将流量发往该目标的出站 SNAT 端口的问题。
如果目标是 Azure 外部的外部终结点,则使用 NAT 网关可获得 64,000 个出站 SNAT 端口。 它还提供了一个专用出站地址,可以不与任何人共享。
如果可能,请对代码进行改进,以使用连接池并避免整个情况。 但更改代理并不是总能那么快,以致于无法及时缓解这种情况。 如果无法及时更改代码,可以利用其他解决方案。 该问题的最佳解决方法是尽量结合使用所有解决方案。 尝试对 Azure 服务使用服务终结点和专用终结点,并对其他服务使用 NAT 网关。
若要详细了解缓解 SNAT 端口耗尽的策略,请参阅 将 SNAT 用于出站连接。 这些策略中的以下策略适用于托管在 Azure 应用服务中的应用和功能。
- 对于池 HTTP 连接,请查看使用 HttpClientFactory 的池 HTTP 连接。
- 有关 SQL Server 连接池的信息,请查看 SQL Server 连接池 (ADO.NET)。
以下文章介绍了如何通过不同的解决方案堆栈实现连接池。
默认情况下,Node.js 的连接不会保持活动状态。
- MySQL
- MongoDB
- PostgreSQL
- SQL Server
HTTP 保持活动状态
Java Database Connectivity (JDBC) 连接池
HTTP 连接池
尽管 PHP 不支持连接池,但你可以尝试使用到后端服务器的持久数据库连接。
MySQL 服务器
- 适用于较新版本的 MySQLi 连接
- 适用于较旧 PHP 版本的 mysql_pconnect
其他数据源
- MySQL
- MariaDB
- PostgreSQL
- Pyodbc
- SQLAlchemy
HTTP 连接池
有关管理 Azure Functions 中的连接的详细信息指针和示例,请参阅 “在 Azure Functions 中管理连接”。
有关更多指南和示例,请参阅 重试模式。
若要为 Node.js 应用实现“保持活动状态”,请参阅我的 Node 应用程序正在发出过多的出站调用。
- 将应用服务计划横向扩展为更多实例。 有关缩放的详细信息,请参阅缩放 Azure 应用服务中的应用。 应用服务计划中的每个辅助角色实例分配有多个 SNAT 端口。 如果将用量分散在多个实例之间,可能会使每个实例的 SNAT 端口用量不超过每个独特远程终结点的建议出站连接数限制(100 个)。
- 考虑转移到应用服务环境 (ASE),其中分配了单个出站 IP 地址,且连接数和 SNAT 端口数限制更高。 在 ASE 中,每个实例的 SNAT 端口数基于 Azure 负载均衡器预分配表。 例如,具有 1-50 个辅助角色实例的 ASE 每个实例有 1,024 个预分配端口,而具有 51-100 个辅助角色实例的 ASE 每个实例有 512 个预分配端口。
避免超过出站 TCP 限制要更容易一些,因为这些限制是按辅助角色的大小设置的。 可以在沙盒跨 VM 数字限制 - TCP 连接中查看限制
限制名称 | 描述 | 小型 (A1) | 中型 (A2) | 大型 (A3) | 隔离层 (ASE) |
---|---|---|---|---|---|
连接 | 整个 VM 的连接数 | 1920 | 3968 | 8064 | 16,000 |
若要避免超过出站 TCP 限制,可以增大辅助角色的大小,或者横向扩展。
了解两种类型的出站连接限制以及应用的作用后,应该就可以更轻松地进行故障排除。 如果你知道自己的应用对同一存储帐户发出许多调用,可以怀疑达到了 SNAT 限制。 如果应用完全通过 Internet 向终结点发出大量的调用,可以怀疑达到了虚拟机限制。
如果你对应用程序的行为认识不充分,以致无法快速判断原因,可以借助应用服务中的某些工具和技术做出判断。
- 若要访问应用服务诊断,请在 Azure 门户中导航到你的应用服务 Web 应用或应用服务环境。 在边栏菜单中,选择“ 诊断”并解决问题。
- 选择 “可用性和性能 ”类别。
- 在该类别下的可用磁贴列表中,选择“SNAT 端口耗尽”磁贴。 做法是将其保持在 128 以下。 如果确实需要,仍可以开具支持票证,支持工程师会从后端为你提取指标。
由于 SNAT 端口使用情况不能作为指标提供,因此无法基于 SNAT 端口使用情况自动缩放,也不能根据 SNAT 端口分配指标配置自动缩放。
TCP 连接和 SNAT 端口并不直接相关。 TCP 连接使用情况检测器包含在任何应用服务应用的 “诊断和解决问题 管理”页中。 搜索短语“TCP 连接”即可找到它。
- SNAT 端口仅用于外部网络流,而 TCP 连接总数包括本地环回连接。
- 如果协议、IP 地址或端口中的流不同,则一个 SNAT 端口可由不同的流共享。 TCP 连接指标统计每个 TCP 连接。
- TCP 连接限制在辅助角色实例级别发生。 Azure 网络出站负载均衡不使用 TCP 连接指标来限制 SNAT 端口。
- TCP连接限制详见沙盒跨 VM 数值限制 - TCP 连接。
- 从 Azure 应用服务源端口添加新的出站 TCP 会话时,现有 TCP 会话会失败。 你可以使用单个 IP 或重新配置后端池成员以避免冲突。
限制名称 | 描述 | 小型 (A1) | 中型 (A2) | 大型 (A3) | 隔离层 (ASE) |
---|---|---|---|---|---|
连接 | 整个 VM 的连接数 | 1920 | 3968 | 8064 | 16,000 |
如果 SNAT 端口耗尽,导致 WebJobs 无法连接到 SQL 数据库,则不会有任何指标显示每个 Web 应用程序进程打开的连接数。 若要查找有问题的 Web 作业,请将多个 Web 作业移到另一个应用服务计划,以确定情况是否有所改善,或者某个计划中仍有问题。 重复该过程,直到找出有问题的 Web 作业。