我需要构建一个 Azure 函数:
HTTP POST
请求HTTP HEAD
请求。但是,还不完全清楚该做什么以及如何运作?
如第二个链接中所示,我当前刚刚声明了一个
private static HttpClient httpClient = new HttpClient();
实例,并在我的 7x HTTP HEAD 调用中重新使用了该实例。
我的问题:
HttpClient
吗?List<Task>()
,然后对它们执行 Task.WhenAll(tasks)
以并行运行它们。这是拨打这些电话的最快方式吗?还有其他建议吗?此函数端点将被多次调用(每秒多次),因此需要尽可能高效以降低成本。
谢谢!
截至 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。就我个人而言,我认为这非常优雅。
是的 - 这仍然是 Azure Functions 1.x 的当前指南(也适用于 2.x),以最好地避免套接字耗尽。静态变量将确保它将被该类的所有实例共享。另一篇涵盖该主题的好文章是 https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
如果依赖注入不可用,或者您有一个在运行时知道的 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;
}