Azure Functions 中的 HttpClient 最佳实践
Posted
技术标签:
【中文标题】Azure Functions 中的 HttpClient 最佳实践【英文标题】:HttpClient best practices in Azure Functions 【发布时间】:2018-07-11 02:59:21 【问题描述】:我需要构建一个 Azure 函数:
响应HTTP POST
请求
根据数据执行 7x HTTP HEAD
请求。
我找到了一些指导 here 和 here
但是,不完全清楚该做什么以及它是如何工作的?
与第二个链接一样,我目前刚刚声明了一个 private static HttpClient httpClient = new HttpClient();
实例,并在我的 7x HTTP HEAD 调用中重新使用了它。
我的问题:
-
这是在无状态 Azure 函数中最有效地使用
HttpClient
吗?
我目前正在为 http 调用建立一个 List<Task>()
,然后对它们执行 Task.WhenAll(tasks)
以并行运行它们。这会是打这些电话的最快方法吗?还有其他建议吗?
这个 Function 端点会被大量调用(每秒多次),因此需要尽可能高效以降低成本。
谢谢!
【问题讨论】:
【参考方案1】:从 2019 年开始,以及运行时的 v2/v3+,您还可以选择use dependency injection in .NET Azure Functions。请注意,这仅适用于 .NET 函数 (C#),而 AFAIK 不适用于其他风格,如 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 核心的 web/api 项目几乎相同。接下来,在您的函数本身中,添加一个构造函数并将依赖项注册为参数。您还想从函数中删除 static
修饰符。一个例子:
public class MyInjectedFunction
private readonly HttpClient _http;
public MyInjectedFunction(HttpClient httpClient)
_http = httpClient;
[FunctionName("my-injected-function")]
public async Task RunAsync([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log)
var response = await _http.GetAsync("https://***.com");
if (response.IsSuccessStatusCode)
log.LogInformation("Okidoki");
else
log.LogError($"response.StatusCode response.ReasonPhrase: ");
通过使用 DI,您也可以将其显式注册为单例。或创建类型化的 HttpClients。就个人而言,我认为这很优雅。
【讨论】:
我在 Azure 文档中读到了这个,但不清楚它是如何在函数中创建 HttpClient 的。显然,Azure 函数有一个主机 DI 容器,它“保存”函数的每个请求实例,并将 HttpClient 作为单例提供给所有函数实例,因此在第一次配置后无法更改 BaseUri。那么,如果它实际上是一个单例并且无法修改,那么配置 HttpClient 的合适位置在哪里?【参考方案2】:是的 - 这仍然是 Azure Functions 1.x(也适用于 2.x)的当前指南,以最好地避免套接字耗尽。静态变量将确保它将与类的所有实例共享。涵盖该主题的另一篇好文章是https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
【讨论】:
谢谢。那篇文章是2016年的吗?最近没有什么表明它仍然是最好的方法吗?不是怀疑你,只是想确定:) 至少就 Azure Functions 的 1.x 和 .net 框架 4.x 而言,自 2016 年以来没有太大变化会影响指导 :) Azure Functions 2.x 虽然可能会引入一些新的选项\最佳实践,因为它位于 .net core 2.1 上。我怀疑该指南在很大程度上是相同的(最大限度地重用),但有一些新的与 httpclient 相关的结构,例如 HttpClientFactory (stevejgordon.co.uk/introduction-to-httpclientfactory-aspnetcore),可能会引入一些新的或额外的选项\指南。 这个解决方案在一般情况下确实不是 HttpClient 的正确用法。持有一个实例也是错误的,因为 DNS 更改无法通过。您最终将失去所有连接。这就是存在 HttpClientFactory 的原因——但仅在 ASP .Net Core 2.1 中。我现在的问题是:我们现在应该做什么? @RPM1984 - 来自 Microsoft 的关于此 can be found here 的官方文档。然而,正如 Zordid 所提到的,如果你可以使用更新的 HttpClientFactory 那就更好了。以上是关于Azure Functions 中的 HttpClient 最佳实践的主要内容,如果未能解决你的问题,请参考以下文章
Azure Functions 中的 HttpClient 最佳实践