排查应用程序网关中的网关无效错误

了解如何排查使用 Azure 应用程序网关时收到的网关无效 (502) 错误。

注意

建议使用 Azure Az PowerShell 模块与 Azure 交互。 请参阅安装 Azure PowerShell 以开始使用。 若要了解如何迁移到 Az PowerShell 模块,请参阅 将 Azure PowerShell 从 AzureRM 迁移到 Az

概述

配置应用程序网关后,可能会出现的一个错误是“服务器错误:502 - Web 服务器在作为网关或代理服务器时收到了无效响应”。 此错误可能是以下主要原因造成的:

  • NSG、UDR 或自定义 DNS 阻止了对后端池成员的访问。
  • 虚拟机规模集的后端 VM 或实例未响应默认的运行状况探测。
  • 自定义运行状况探测的配置无效或不正确。
  • Azure 应用程序网关的后端池未配置或为空
  • 虚拟机规模集中没有正常运行的 VM 或实例。
  • 用户请求出现请求超时或连接问题

网络安全组、用户定义的路由或自定义 DNS 问题

原因

如果对后端的访问由于存在 NSG、UDR 或自定义 DNS 而被阻止,则应用程序网关实例将无法联系后端池。 此问题会导致探测故障并引发 502 错误。

NSG/UDR 可能存在于应用程序网关子网中,也可能存在于部署了应用程序 VM 的子网中。

类似地,VNet 中存在自定义 DNS 也可能会导致问题。 用于后端池成员的 FQDN 无法由用户为 VNet 配置的 DNS 服务器正确解析。

解决方案

通过执行以下步骤验证 NSG、UDR 和 DNS 配置:

  1. 检查与应用程序网关子网关联的 NSG。 确保与后端的通信没有被阻止。 有关详细信息,请参阅网络安全组

  2. 检查与应用程序网关子网关联的 UDR。 确保 UDR 没有将流量引离后端子网。 例如,检查到网络虚拟设备的路由或通过 ExpressRoute/VPN 播发到应用程序网关子网的默认路由。

    $vnet = Get-AzVirtualNetwork -Name vnetName -ResourceGroupName rgName
    Get-AzVirtualNetworkSubnetConfig -Name appGwSubnet -VirtualNetwork $vnet
    
  3. 检查包含后端 VM 的有效 NSG 和路由

    Get-AzEffectiveNetworkSecurityGroup -NetworkInterfaceName nic1 -ResourceGroupName testrg
    Get-AzEffectiveRouteTable -NetworkInterfaceName nic1 -ResourceGroupName testrg
    
  4. 检查 VNet 中是否存在自定义 DNS。 可以通过查看输出中的 VNet 属性的详细信息来检查 DNS。

    Get-AzVirtualNetwork -Name vnetName -ResourceGroupName rgName 
    DhcpOptions            : {
                               "DnsServers": [
                                 "x.x.x.x"
                               ]
                             }
    
  5. 如果存在,请确保 DNS 服务器能够正确解析后端池成员的 FQDN。

默认运行状况探测出现问题

原因

此外,出现 502 错误通常意味着默认的运行状况探测无法访问后端 VM。

预配某个应用程序网关实例时,该实例会使用 BackendHttpSetting 的属性自动将默认的运行状况探测配置到每个 BackendAddressPool。 无需用户输入即可设置此探测。 具体而言,在配置负载均衡规则时,会在 BackendHttpSetting 与 BackendAddressPool 之间建立关联。 默认探测是针对其中每个关联配置的,而应用程序网关会在 BackendHttpSetting 元素中指定的端口上,与 BackendAddressPool 中每个实例发起周期性运行状况检查连接。

下表列出了与默认运行状况探测关联的值:

探测属性 说明
探测 URL http://127.0.0.1/ URL 路径
时间间隔 30 探测间隔(秒)
超时 30 探测超时(秒)
不正常阈值 3 探测重试计数。 连续探测失败计数达到不正常阈值后,将后端服务器标记为故障。

解决方案

  • 请求的主机值将设置为 127.0.0.1。 确定默认站点已配置且正在侦听 127.0.0.1。
  • 请求的协议由 BackendHttpSetting 协议确定。
  • URI 路径将设置为 /
  • 如果 BackendHttpSetting 指定的端口不是 80,则应将默认站点配置为侦听指定的端口。
  • protocol://127.0.0.1:port 的调用应返回 HTTP 结果代码 200。 应在 30 秒超时期限内返回此代码。
  • 确保配置的端口已打开,并且没有任何防火墙或 Azure 网络安全组在配置的端口上阻止传入或传出流量。
  • 如果对 Azure 经典 VM 或云服务使用 FQDN 或公共 IP,请确保打开相应的终结点
  • 如果 VM 是通过 Azure 资源管理器配置的并且位于应用程序网关部署所在的 VNet 的外部,则必须将网络安全组配置为允许在所需端口上进行访问。

有关详细信息,请参阅应用程序网关基础结构配置

自定义运行状况探测出现问题

原因

自定义运行状况探测能够对默认探测行为提供更大的弹性。 使用自定义探测时,可以配置探测间隔、要测试的 URL 和路径,以及在将后端池实例标记为不正常之前可接受的失败响应次数。

添加了以下附加属性:

探测属性 说明
名称 探测的名称。 此名称用于在后端 HTTP 设置中引用探测。
协议 用于发送探测的协议。 探测使用后端 HTTP 设置中定义的协议
主机 用于发送探测的主机名。 仅当应用程序网关上配置了多站点时才适用。 这与 VM 主机名不同。
`Path` 探测的相对路径。 有效路径以“/”开头。 将探测发送到 <protocol>://<host>:<port><path>
时间间隔 探测间隔(秒)。 这是每两次连续探测之间的时间间隔。
超时 探测超时(秒)。 如果在此超时期间内未收到有效响应,则将探测标记为失败。
不正常阈值 探测重试计数。 连续探测失败计数达到不正常阈值后,将后端服务器标记为故障。

解决方案

验证自定义运行状况探测是否已正确配置,如上表所示。 除了上述故障排除步骤以外,另请确保符合以下要求:

  • 确保已根据指南正确指定了探测。
  • 如果在应用程序网关中配置了单站点,则默认情况下,除非已在自定义探测中进行配置,否则应将主机名指定为 127.0.0.1
  • 确保对 http://<host>:<port><path> 的调用返回 HTTP 结果代码 200。
  • 确保 Interval、Timeout 和 UnhealtyThreshold 都在可接受的范围内。
  • 如果使用 HTTPS 探测器,请通过在后端服务器本身上配置回退证书,确保后端服务器不需要 SNI。

请求超时

原因

收到用户请求后,应用程序网关会将配置的规则应用到该请求,并将其路由到后端池实例。 应用程序网关将等待一段可配置的时间间隔,以接收后端实例做出的响应。 默认情况下,此间隔为 20 秒。 在应用程序网关 v1 中,如果应用程序网关在此时间间隔内未收到后端应用程序的响应,则用户请求会收到 502 错误。 在应用程序网关 v2 中,如果应用程序网关在此时间间隔内未收到来自后端应用程序的响应,则会针对第二个后端池成员尝试该请求。 如果第二个请求失败,用户请求会收到 504 错误。

解决方案

应用程序网关允许通过 BackendHttpSetting 配置此设置,并可将此设置应用到不同的池。 不同的后端池可以有不同的 BackendHttpSetting,因此可配置不同的请求超时。

    New-AzApplicationGatewayBackendHttpSettings -Name 'Setting01' -Port 80 -Protocol Http -CookieBasedAffinity Enabled -RequestTimeout 60

BackendAddressPool 为空

原因

如果应用程序网关没有在后端地址池中配置 VM 或虚拟机规模集,则无法路由任何客户请求,并将发出网关无效错误。

解决方案

确保后端地址池不为空。 这可以通过 PowerShell、CLI 或门户来实现。

Get-AzApplicationGateway -Name "SampleGateway" -ResourceGroupName "ExampleResourceGroup"

上述 cmdlet 的输出应包含非空后端地址池。 以下示例显示了返回的两个池,其中配置了后端 VM 的 FQDN 或 IP 地址。 BackendAddressPool 的预配状态必须是“Succeeded”。

BackendAddressPoolsText:

[{
    "BackendAddresses": [{
        "ipAddress": "10.0.0.10",
        "ipAddress": "10.0.0.11"
    }],
    "BackendIpConfigurations": [],
    "ProvisioningState": "Succeeded",
    "Name": "Pool01",
    "Etag": "W/\"00000000-0000-0000-0000-000000000000\"",
    "Id": "/subscriptions/<subscription id>/resourceGroups/<resource group name>/providers/Microsoft.Network/applicationGateways/<application gateway name>/backendAddressPools/pool01"
}, {
    "BackendAddresses": [{
        "Fqdn": "xyx.chinacloudapp.cn",
        "Fqdn": "abc.chinacloudapp.cn"
    }],
    "BackendIpConfigurations": [],
    "ProvisioningState": "Succeeded",
    "Name": "Pool02",
    "Etag": "W/\"00000000-0000-0000-0000-000000000000\"",
    "Id": "/subscriptions/<subscription id>/resourceGroups/<resource group name>/providers/Microsoft.Network/applicationGateways/<application gateway name>/backendAddressPools/pool02"
}]

BackendAddressPool 中存在运行不正常的实例

原因

如果 BackendAddressPool 的所有实例都运行不正常,则应用程序网关不会包含任何要将用户请求路由到其中的后端。 当后端实例运行正常但尚未部署所需的应用程序时,也可能会发生此情况。

解决方案

确定实例正常运行且已正确配置了应用程序。 检查后端实例是否能够从同一个 VNet 中的另一个 VM 响应 ping。 如果实例中配置了公共终结点,请确保能够为发送到 Web 应用程序的浏览器请求提供服务。

上游 SSL 证书不匹配

原因

后端服务器上安装的 TLS 证书与在主机请求头中收到的主机名不匹配。

在启用端到端 TLS 的方案中(这种配置是通过编辑相应的“后端 HTTP 设置”,并将“后端协议”配置设置更改为 HTTPS 来实现的),必须确保后端服务器中安装的 TLS 证书的 CNAME 与在 HTTP 主机头请求中传入后端的主机名相匹配。

提醒一下,在“后端 HTTP 设置”中启用协议 HTTPS 而不是 HTTP 选项的效果是,应用程序网关实例与后端服务器之间发生的通信的第二个部分将使用 TLS 进行加密。

由于应用程序网关默认会向后端发送它从客户端收到的同一个 HTTP 主机头,因此你需要确保后端服务器上安装的 TLS 证书,是使用与 HTTP 主机头中后端服务器收到的主机名匹配的 CNAME 颁发的。 请记住,除非另有指定,否则此主机名与从客户端收到的主机名相同。

例如:

假设某个应用程序网关为域 www.contoso.com 的 HTTPS 请求提供服务。 你可以将域 contoso.com 委托给 Azure DNS 公用区域,并使该区域中的某条 DNS A 记录将 www.contoso.com 指向为请求提供服务的特定应用程序网关的公共 IP。

在该应用程序网关上,应该针对主机 www.contoso.com 配置一个侦听器,并为该侦听器创建一个强制“后端 HTTP 设置”使用协议 HTTPS(确保端到端 TLS)的规则。 可在同一规则中配置一个后端池,其中包含两个运行 IIS 的 VM 作为 Web 服务器。

我们知道,在规则的“后端 HTTP 设置”中启用 HTTPS 会导致应用程序网关实例与后端服务器之间发生的通信的第二个部分使用 TLS。

如果后端服务器未为 CNAME www.contoso.com 或 *.contoso.com 颁发 TLS 证书,则请求将会失败并出现“服务器错误: 502 - Web 服务器在充当网关或代理服务器时收到了无效响应”,因为上游 SSL 证书(安装在后端服务器中的证书)与主机头中的主机名不匹配,因此 TLS 协商会失败。

www.contoso.com --> 应用程序网关前端 IP --> 附带规则的侦听器,该规则将“后端 HTTP 设置”配置为使用协议 HTTPS 而不是 HTTP --> 后端池 --> Web 服务器(需要为 www.contoso.com 安装 TLS 证书)

解决方案

后端服务器中安装的 TLS 证书的 CNAME 必须与 HTTP 后端设置中配置的主机名匹配,否则应用程序网关实例与后端之间发生的端到端通信的第二个部分将会失败并显示消息“上游 SSL 证书不匹配”,同时会引发“服务器错误: 502 - Web 服务器在充当网关或代理服务器时收到了无效响应”

后续步骤

如果上述步骤无法解决问题,请开具支持票证