转发请求时的 ClientConnectionFailure

ClientConnectionFailure at forward-request

我有一个 Angular Web 应用程序,它由 C# Web Api 支持,这有助于与 Azure Function App 对话。

粗略的示例流程如下所示:

对于较大的负载,下载请求失败并在 Application Insights 中出现以下错误:

"ClientConnectionFailure at forward-request"

此错误每次都恰好在 2 分钟发生,除非负载足够小。

这让我相信在这种情况下我理解为客户端的 Function App 正在超时并取消请求。

但是使用 Postman 通过 Azure Function App 的本地实例测试具有完全相同参数的 GET,有效负载被成功检索。

所以问题不是 Azure Function App,因为它在 Postman 中没有像使用 WebApp 时那样超时。

这让我想到了三种不同的可能性:

  1. C# WebApi 超时并在 APIM 可以完全响应之前取消请求
  2. WebApp 本身正在超时。
  3. 互联网浏览器 (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 中有几个超时属性,例如 allScriptsTimeoutdefaultTimeoutInterval

增加这些没有效果。

** 最后一种可能是 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 中执行此操作,

  1. 转到您的 APIM
  2. API
  3. Select 你的函数应用
  4. 单击 Inbound Processing
  5. 下的代码图标 </>

或者,如果您只想对一个 operation/endpoint 执行此操作,请在执行第 4 步之前单击一个 operation/endpoint。

在本地(Azure 外部)、Web 应用程序(前端)、Web api、函数应用程序(后端)测试解决方案的每个组件后,很明显问题是由 Azure 本身引起的,即 Azure 负载均衡器空闲超时的默认 4 分钟。

我通过计时失败的请求进行了双重检查,并且总是有 4 分钟。

后端代码发送请求的方式是一致的,对于较大的数据集,这会导致它达到负载平衡器的超时。

看起来负载平衡器超时是可配置的,但这看起来我无法更改。

所以解决方案:在后端多写efficiet/better代码。