如何解决当 Web 应用绑定了主机名而无法使用应用程序网关的问题
问题描述
当 Web 应用绑定了主机名并使用 Azure 应用程序网关作为负载均衡器的情形下,该网页可能无法正常访问。
问题分析
访问网页时,浏览器会直接弹出下面的报错:
502 - Web server received an invalid response while acting as a gateway or proxy server.
There is a problem with the page you are looking for, and it cannot be displayed. When the Web server (while acting as a gateway or proxy) contacted the upstream content server, it received an invalid response from the content server.
解决方法
Azure 应用程序网关会通过探测机制去了解后端服务器的健康状态,其默认会使用 HTTP 协议作为探测机制。如果我们没有配置自定义探针,应用程序网关会发送主机名为 127.0.0.1 路径为 “/ ” 的 HTTP GET 请求。当后端 Web 服务器绑定了主机名,这会导致 Web 服务器不会对应用程序网关的 HTTP 请求返回正确的 HTTP 响应,进而会导致应用程序网关向客户端抛出 502 的报错。
下面的网络数据报文显示了程序网关发送的默认探测包,可以看到请求路径为 “/ ”,请求主机名为 127.0.0.1。
Frame: Number = 895, Captured Frame Length = 131, MediaType = ETHERNET
+ Ethernet: Etype = Internet IP (IPv4),DestinationAddress:[00-17-FA-00-64-54],SourceAddress:[F8-72-EA-E0-26-81]
+ Ipv4: Src = 10.30.0.56, Dest = 10.30.0.52, Next Protocol = TCP, Packet ID = 13920, Total IP Length = 117
+ Tcp: Flags=...AP..., SrcPort=64902, DstPort=HTTP(80), PayloadLen=77, Seq=2534951712 - 2534951789, Ack=3462157853, Win=4121 (scale factor 0x8) = 1054976
- Http: Request, GET /
Command: GET
- URI: /
Location: /
ProtocolVersion: HTTP/1.1
Connection: Keep-Alive
Host: 127.0.0.1
Max-Forwards: 10
HeaderEnd: CRLF
要解决该问题,我们需要对应用程序网关配置自定义探针。应用程序网关可以配置的自定义探针配置如下:
- Name - 自定义探测的引用名称。
- Protocol - 使用的协议(可能的值为 HTTP 或 HTTPS)。
- Host 和 Path - 应用程序网关为了确定实例运行状况而调用的完整 URL 路径。例如,如果网站为 http://www.contoso.com/,则可以为 “http://www.contoso.com/path/custompath.htm” 配置自定义探测,使探测检查能够获得成功的 HTTP 响应。
- Interval - 配置探测检查间隔,以秒为单位。
- Timeout - 定义 HTTP 响应检查的探测超时。
- UnhealthyThreshold - 将后端实例标记为不正常所需的失败 HTTP 响应数目。
对于使用经典模式创建的应用程序网关只能使用 PowerShell 来进行操作。具体操作步骤如下:
运行下面的 PowerShell 命令导出应用程序网关的配置信息。
Get-AzureApplicationGatewayConfig -Name <application gateway name> -Exporttofile "<path to file>"
打开导出的文件并找到 FrontendPorts 部分,并在其之后添加 Probes 字段。Host 部分就填写 Web 服务器中所绑定的主机名,其他部分可以根据实际需求进行配置。
<FrontendPorts> <FrontendPort> <Name>FrontendPort1</Name> <Port>80</Port> </FrontendPort> </FrontendPorts> <Probes> <Probe> <Name>Probe01</Name> <Protocol>Http</Protocol> <Host>www.contoso.com</Host> <Path>/</Path> <Interval>15</Interval> <Timeout>15</Timeout> <UnhealthyThreshold>5</UnhealthyThreshold> </Probe> </Probes>
在 XML 的 backendHttpSettings 节中,添加字段 “Probe01” 启用在步骤 2 中创建的探针,示例如下:
<BackendHttpSettings> <Name>setting1</Name> <Port>80</Port> <Protocol>Http</Protocol> <CookieBasedAffinity>Enabled</CookieBasedAffinity> <RequestTimeout>30</RequestTimeout> <Probe>Probe01</Probe> </BackendHttpSettings>
运行下面的命令对应用程序网关进行配置。
Set-AzureApplicationGatewayConfig -Name <application gateway name> -Configfile "<path to file>"
注意:请使用最新版本的 Azure PowerShell 来进行配置,如果使用的 PowerShell 版本较老可能会导致该操作不成功。
对于使用 ARM 模式创建的应用程序网关,我们可以直接在 Portal 直接进行配置。
如下图所示,点击“运行状况探测”,添加自定义探测并指定自定义探测的名称和主机名。
点击 “HTTP 设置”,找到对应的 HTTP 设置然后勾选 “使用自定义探测” 并选择刚才定义的探测规则,保存设置即可。