Azure函数DbContext请求延迟-在启动时连接到数据库?



我有一个Azure Functions应用程序,我试图尽可能地消除请求延迟。为了应对冷启动时间,我们已经升级了Azure功能计划,以确保我们通常有一个或多个预热的实例准备就绪。

然而,即使有预热的实例,对新启动的函数的第一次HttpTrigger调用也有延迟,因为它需要建立到数据库的连接。在DataContext实例化之前,似乎没有建立数据库连接,而实例化是在HttpTrigger需要它之前才发生的。在向数据库发出第一个请求之后,一切都非常高效。

我使用依赖注入来创建一个DbContextPool在我的FunctionsStartup类:

services.AddDbContextPool<DataContext>(options => { 
options.UseSqlServer(connectionString);
});

我知道建立数据库连接自然需要一点时间,但是有没有办法让Azure函数在启动时获得连接池,而不是等到第一个HttpTrigger实例化我的DbContext并连接到数据库?

多亏了这个答案,我才想出了一个解决方案。这个解决方案的伟大之处在于,它不仅可以用于预暖数据库/DbContext连接,还可以用于预暖所有类型的连接(例如,Storage Accounts, Key Vault access,等等)。

using System;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host.Config;
using Microsoft.Azure.WebJobs.Hosting;
using Microsoft.Extensions.DependencyInjection;
[assembly: WebJobsStartup(typeof(MyCompany.MyProduct.MyFunctionAppInitializer), "MyFunctionAppInitializer")]
namespace MyCompany.MyProduct;
public class MyFunctionAppInitializer : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
builder.AddExtension<MyFunctionAppInitializerConfigProvider>();
}
}
internal class MyFunctionAppInitializerConfigProvider : IExtensionConfigProvider
{
private readonly IServiceScopeFactory scopeFactory;
public MyFunctionAppInitializerConfigProvider(IServiceScopeFactory scopeFactory)
{
this.scopeFactory = scopeFactory;
}
public void Initialize(ExtensionConfigContext context)
{
using IServiceScope scope = scopeFactory.CreateScope();
Task preWarmTask = PreWarmConnections(scope.ServiceProvider);
preWarmTask.Wait();
}

private static async Task PreWarmConnections(IServiceProvider serviceProvider)
{
// Connect to Database
var dbContext = serviceProvider.GetService<MyDbContext>();
await dbContext.PingDatabase();

// Connect to Storage Access
await MyStorageAccess.PingStorageAccess();

// Connect to Signing Key Vault
MyAuthorization.InitializeCryptoClient();
}
}

作为一点背景:如果您像我一样,第一次尝试将DbContext实例化/连接放在Startup类中,那么当您尝试将其部署到Function环境中时,您将很快发现会得到各种崩溃错误(通常与日志记录相关)。这是因为Function App还没有在该类的Configure()方法中完全初始化。

使用WebJobStartup调用,然而,似乎发生在一切都整齐初始化之后,但仍然在启动实例时。在实践中,这使我能够获得我需要的所有连接,这样,向我的Function应用程序发出的请求就会非常灵活。

相关内容

  • 没有找到相关文章

最新更新