转发请求时的 ClientConnectionFailure
ClientConnectionFailure at forward-request
我有一个 Angular Web 应用程序,它由 C# Web Api 支持,这有助于与 Azure Function App 对话。
粗略的示例流程如下所示:
- Angular Web 应用程序(使用选定的参数按下载)-> 将 GET 请求发送到 API 管理服务
- API 管理服务调用 C# Web Api
- C# Web Api 然后响应 APIM,后者又调用 Azure Function App 进行进一步处理
来自外部来源的数据
- 准备好 csv 文件后,数据有效负载将下载到打开 Web 应用程序的浏览器中
对于较大的负载,下载请求失败并在 Application Insights 中出现以下错误:
"ClientConnectionFailure at forward-request"
此错误每次都恰好在 2 分钟发生,除非负载足够小。
这让我相信在这种情况下我理解为客户端的 Function App 正在超时并取消请求。
但是使用 Postman 通过 Azure Function App 的本地实例测试具有完全相同参数的 GET,有效负载被成功检索。
所以问题不是 Azure Function App,因为它在 Postman 中没有像使用 WebApp 时那样超时。
这让我想到了三种不同的可能性:
- C# WebApi 超时并在 APIM 可以完全响应之前取消请求
- WebApp 本身正在超时。
- 互联网浏览器 (Chrome) 超时。 (Chrome 有 5 分钟的硬性不可更改超时,所以不太可能)
#1。为了解决第一个选项,我升级了在相关下载操作中创建的 HttpClient 的超时:
public aync Task<HttpResponseMessage> DownloadIt(blah)
{
HttpClient client = getHttpClient();
client.Timeout = TimeSpan.FromMilliseconds(Convert.ToDouble(600000)); // 10 minutes
var request = new HttpRequestMessage(HttpMethod.Get, buildQueryString(blah, client.BaseAddress));
return await client.SendAsync(request);
}
private HttpClient getHttpClient()
{
return _httpClientFactory.CreateClient("blah");
}
这没有效果,因为观察到相同的错误。
#2。 protractor.conf.js 中有几个超时属性,例如 allScriptsTimeout
和 defaultTimeoutInterval
。
增加这些没有效果。
** 最后一种可能是 APIM 本身超时了,但是查看相关 API 的 APIM 策略,没有 forward-请求 属性,有超时,根据 Microsoft 的默认意思,APIM 没有超时。
https://docs.microsoft.com/en-us/azure/api-management/api-management-advanced-policies
我尝试了几种不同的策略,但都无济于事。
确实有超时,因为ClientConnectionFailure表示客户端关闭了与API管理(APIM)的连接,而APIM尚未return响应它(客户端),在这种情况下,它正在将请求转发到后端(forward-request)
要调试此类问题,最好的方法是收集APIM inspector trace来检查APIM管道内的请求处理,注意每个花费的时间请求的部分 - 入站、后端、出站。花费最多时间的部分可能是罪魁祸首(或其依赖项)。希望这可以帮助您找到问题所在。
您可以在整个函数应用程序或单个端点上显式设置转发请求,例如:
<backend>
<forward-request timeout="1800" />
</backend>
时间以秒为单位(此处为 1800*60 = 60 分钟)
要在 APIM 中执行此操作,
- 转到您的 APIM
- API
- Select 你的函数应用
- 单击
Inbound Processing
下的代码图标 </>
或者,如果您只想对一个 operation/endpoint 执行此操作,请在执行第 4 步之前单击一个 operation/endpoint。
在本地(Azure 外部)、Web 应用程序(前端)、Web api、函数应用程序(后端)测试解决方案的每个组件后,很明显问题是由 Azure 本身引起的,即 Azure 负载均衡器空闲超时的默认 4 分钟。
我通过计时失败的请求进行了双重检查,并且总是有 4 分钟。
后端代码发送请求的方式是一致的,对于较大的数据集,这会导致它达到负载平衡器的超时。
看起来负载平衡器超时是可配置的,但这看起来我无法更改。
所以解决方案:在后端多写efficiet/better代码。
我有一个 Angular Web 应用程序,它由 C# Web Api 支持,这有助于与 Azure Function App 对话。
粗略的示例流程如下所示:
- Angular Web 应用程序(使用选定的参数按下载)-> 将 GET 请求发送到 API 管理服务
- API 管理服务调用 C# Web Api
- C# Web Api 然后响应 APIM,后者又调用 Azure Function App 进行进一步处理 来自外部来源的数据
- 准备好 csv 文件后,数据有效负载将下载到打开 Web 应用程序的浏览器中
对于较大的负载,下载请求失败并在 Application Insights 中出现以下错误:
"ClientConnectionFailure at forward-request"
此错误每次都恰好在 2 分钟发生,除非负载足够小。
这让我相信在这种情况下我理解为客户端的 Function App 正在超时并取消请求。
但是使用 Postman 通过 Azure Function App 的本地实例测试具有完全相同参数的 GET,有效负载被成功检索。
所以问题不是 Azure Function App,因为它在 Postman 中没有像使用 WebApp 时那样超时。
这让我想到了三种不同的可能性:
- C# WebApi 超时并在 APIM 可以完全响应之前取消请求
- WebApp 本身正在超时。
- 互联网浏览器 (Chrome) 超时。 (Chrome 有 5 分钟的硬性不可更改超时,所以不太可能)
#1。为了解决第一个选项,我升级了在相关下载操作中创建的 HttpClient 的超时:
public aync Task<HttpResponseMessage> DownloadIt(blah)
{
HttpClient client = getHttpClient();
client.Timeout = TimeSpan.FromMilliseconds(Convert.ToDouble(600000)); // 10 minutes
var request = new HttpRequestMessage(HttpMethod.Get, buildQueryString(blah, client.BaseAddress));
return await client.SendAsync(request);
}
private HttpClient getHttpClient()
{
return _httpClientFactory.CreateClient("blah");
}
这没有效果,因为观察到相同的错误。
#2。 protractor.conf.js 中有几个超时属性,例如 allScriptsTimeout
和 defaultTimeoutInterval
。
增加这些没有效果。
** 最后一种可能是 APIM 本身超时了,但是查看相关 API 的 APIM 策略,没有 forward-请求 属性,有超时,根据 Microsoft 的默认意思,APIM 没有超时。 https://docs.microsoft.com/en-us/azure/api-management/api-management-advanced-policies
我尝试了几种不同的策略,但都无济于事。
确实有超时,因为ClientConnectionFailure表示客户端关闭了与API管理(APIM)的连接,而APIM尚未return响应它(客户端),在这种情况下,它正在将请求转发到后端(forward-request)
要调试此类问题,最好的方法是收集APIM inspector trace来检查APIM管道内的请求处理,注意每个花费的时间请求的部分 - 入站、后端、出站。花费最多时间的部分可能是罪魁祸首(或其依赖项)。希望这可以帮助您找到问题所在。
您可以在整个函数应用程序或单个端点上显式设置转发请求,例如:
<backend>
<forward-request timeout="1800" />
</backend>
时间以秒为单位(此处为 1800*60 = 60 分钟)
要在 APIM 中执行此操作,
- 转到您的 APIM
- API
- Select 你的函数应用
- 单击
Inbound Processing
下的代码图标
</>
或者,如果您只想对一个 operation/endpoint 执行此操作,请在执行第 4 步之前单击一个 operation/endpoint。
在本地(Azure 外部)、Web 应用程序(前端)、Web api、函数应用程序(后端)测试解决方案的每个组件后,很明显问题是由 Azure 本身引起的,即 Azure 负载均衡器空闲超时的默认 4 分钟。
我通过计时失败的请求进行了双重检查,并且总是有 4 分钟。
后端代码发送请求的方式是一致的,对于较大的数据集,这会导致它达到负载平衡器的超时。
看起来负载平衡器超时是可配置的,但这看起来我无法更改。
所以解决方案:在后端多写efficiet/better代码。