【问题标题】:HttpClient requests not working for a particular domain in AzureHttpClient 请求不适用于 Azure 中的特定域
【发布时间】:2020-11-19 10:29:49
【问题描述】:

我有一个 Azure 函数,它向 URL 发送请求并发回响应。对于来自特定域(机密)的 URL,此函数一直失败并出现超时错误。

为了调试它,我创建了一个非常小的 Azure 函数:

var content = string.Empty;
using (var response = await _httpClient.GetAsync(url))
{
    response.EnsureSuccessStatusCode();
    content = await response.Content.ReadAsByteArrayAsync();
}
return new OkObjectResult(content);

此代码在本地运行良好。当我尝试使用已部署的 Azure 功能时,它适用于我尝试过的所有其他域(例如:https://google.com),但在尝试大约 90 秒后,它会遇到特定域的请求超时错误。错误发生在以下特定行:_httpClient.GetAsync(url)。同样,它适用于本地的这个(机密)域。

我尝试将 Azure 功能部署到两个完全不同的 Azure 服务计划和区域。结果相同。它不适用于来自所需域的 URL。适用于其他域的 URL。

错误:

System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..

更新(解决方案):

我尝试从 Postman 发送请求,从那里复制 C# 代码并将其部署到 Azure 函数,现在它正在为有问题的域工作。如下所示:

var client = new RestClient(url);
client.Timeout = -1;
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);

这里的关键是client.Timeout = -1,似乎已经解决了问题。

现在,在我的原始代码中,我尝试在启动配置和单个请求级别将 HttpClient 的超时设置为 Timeout.InfiniteTimeSpan,但它不起作用。

services.AddHttpClient("AzureTestClient", options =>
{
    options.Timeout = Timeout.InfiniteTimeSpan;
});

我在 HttpClient 解决方案中是否设置了错误的超时时间?

【问题讨论】:

  • 您是否尝试过例如从 Azure VM 调用 URL?
  • @silent 我没有尝试过使用 Azure VM。我尝试了来自 AppInsights Availability 的 URL ping 测试并返回了成功响应。
  • 猜测:由于垃圾邮件,该服务器正在阻止来自 Azure IP 地址范围的所有请求。
  • @IanKemp 我为有问题的域尝试了 tcpping 以及来自 AppService 控制台的 URL 的 curl。两者都有效。
  • 您能否提供有关您拥有的服务计划的更多信息?同样对于机密域,它是否使用自签名证书?

标签: c# azure .net-core azure-functions


【解决方案1】:
  1. 如果您使用的是消费计划,那么机密 URL 可能需要将整个 Azure 数据中心列入白名单。您可以按照指南 here 或考虑将消费计划升级到 premium 并拥有一个专用的链接 VNET。 也许您的本地计算机已经链接到域/白名单,因此 azure 函数在不同的范围内运行。

  2. 另一个原因可能是 URL 返回了一个不同的 HttpStatusCode,它不是成功的范围 (200-299),所以它在旧代码中显示“EnsureSuccessStatusCode”而失败?

通常对于 http 代码初始化,我做了类似的事情:

public void Configure(IWebJobsBuilder builder)
    {
        builder.Services.AddHttpClient("AzureTestClient",
            options => { options.Timeout = Timeout.InfiniteTimeSpan; });
    }

然后当我想使用它时,我确实喜欢在任何其他功能中使用它并且它起作用了:

var client = clientFactory.CreateClient("AzureTestClient");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多