Azure Functions 中的 HttpClient 最佳实践

问题描述 投票:0回答:3

我需要构建一个 Azure 函数:

  • 响应
    HTTP POST
    请求
  • 根据数据进行 7x
    HTTP HEAD
    请求。

我在这里这里

找到了一些指导

但是,还不完全清楚该做什么以及如何运作?

如第二个链接中所示,我当前刚刚声明了一个

private static HttpClient httpClient = new HttpClient();
实例,并在我的 7x HTTP HEAD 调用中重新使用了该实例。

我的问题:

  1. 这是在无状态 Azure 函数中最有效地使用
    HttpClient
    吗?
  2. 我目前只是为 http 调用构建一个
    List<Task>()
    ,然后对它们执行
    Task.WhenAll(tasks)
    以并行运行它们。这是拨打这些电话的最快方式吗?还有其他建议吗?

此函数端点将被多次调用(每秒多次),因此需要尽可能高效以降低成本。

谢谢!

c# .net azure httpclient azure-functions
3个回答
27
投票

截至 2019 年,以及运行时的 v2/v3+,您还可以选择在 .NET Azure Functions 中使用依赖项注入。请注意,这仅适用于 .NET 函数 (C#),据我所知不适用于其他风格,例如 Python、JavaScript/TypeScript 等。

简单的答案是,您可以将 Startup.cs 类添加到注册依赖项的 Azure 函数中:

[assembly: FunctionsStartup(typeof(MyInjectedFunction.Startup))]

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        // Note: Only register dependencies, do not depend or request those in Configure().
        // Dependencies are only usable during function execution, not before (like here).
        
        builder.Services.AddHttpClient();
        // builder.Services.AddSingleton<ILoggerProvider, MyLoggerProvider>();
    }
}

与任何其他具有 dotnet core 的 Web/API 项目几乎相同。接下来,在函数本身中,添加构造函数并将依赖项注册为参数。您还想从函数中删除

static
修饰符。一个例子: 参考:https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection#register-services

public class MyInjectedFunction
{
    private readonly HttpClient _http;
    
    public MyInjectedFunction(IHttpClientFactory httpClientFactory)
    {
        _http = httpClientFactory.CreateClient();
    }
    
    [FunctionName("my-injected-function")]
    public async Task RunAsync([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log)
    {
        var response = await _http.GetAsync("https://stackoverflow.com");
        
        if (response.IsSuccessStatusCode)
            log.LogInformation("Okidoki");
        else
            log.LogError($"{response.StatusCode} {response.ReasonPhrase}: ");
    }
}

通过使用 DI,您也可以显式地将其注册为单例。或者创建类型化的 HttpClient。就我个人而言,我认为这非常优雅。


8
投票

是的 - 这仍然是 Azure Functions 1.x 的当前指南(也适用于 2.x),以最好地避免套接字耗尽。静态变量将确保它将被该类的所有实例共享。另一篇涵盖该主题的好文章是 https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong


0
投票

如果依赖注入不可用,或者您有一个在运行时知道的 HttpClient 的动态列表,那么这里的解决方案可能会很有用。请参阅文档

  • 将 HttpClient 实例化移动到函数外部定义的静态实例,如本例所示。
  • 通过依赖注入使用 IHttpClientFactory 向您的函数提供 HttpClient。这是修复此违规的推荐方法。 )

这是第一个选项 - 使用静态实例。它将所有 HttpClient 存储为静态列表并通过 Uri 访问它们。如果已存在于列表中,则将重用该客户端,否则将创建该客户端并将其添加到列表中。

        private static List<HttpClient> clients = new List<HttpClient>();

        private static HttpClient GetClient(Uri url)
        {
            var client = clients?.FirstOrDefault(x => x.BaseAddress == url);
            if (client == null)
            {
                client = new HttpClient(new HttpClientHandler() { UseCookies = false, MaxConnectionsPerServer = 1000 })
                {
                    BaseAddress = url,
                    Timeout = new TimeSpan(0, 2, 0)
                };
            }
            clients.Add(client);
            return client;
        }
© www.soinside.com 2019 - 2024. All rights reserved.