Azure Function创建到PostgreSQL的连接过多

Sco*_*y H 9 postgresql azure npgsql azure-functions azure-durable-functions

我有一个Azure耐用功能,可与也托管在Azure中的PostgreSQL数据库进行交互。

PostgreSQL数据库的连接限制为50,此外,我的连接字符串将连接池的大小限制为40,从而为超级用户/管理员连接留出了空间。

尽管如此,在某些负载下我还是得到了错误

53300:剩余的连接插槽保留用于非复制超级用户连接

Microsoft的这份文档似乎很相关,但是似乎我不能制作一个静态客户端,并且正如我提到的那样,

因为您仍然可以用尽连接,所以应该优化与数据库的连接。

我有这种方法

private IDbConnection GetConnection()
{
    return new NpgsqlConnection(Environment.GetEnvironmentVariable("PostgresConnectionString"));
}
Run Code Online (Sandbox Code Playgroud)

当我想与PostgreSQL交互时,我喜欢这样

using (var connection = GetConnection())
{
    connection.Open();
    return await connection.QuerySingleAsync<int>(settings.Query().Insert, settings);
}
Run Code Online (Sandbox Code Playgroud)

因此,我正在创建(和布置)许多NpgsqlConnection对象,但是根据,这应该没问题,因为连接池是在后台处理的。但是有关Azure Functions的某些信息可能会使这种想法无效。

我注意到我最终有很多空闲连接(来自pgAdmin): pgAdmin连接图 基于此,我尝试摆弄Npgsql连接参数(Connection Idle Lifetime,,Timeout和)Pooling,但连接过多的问题似乎一直持续到某种程度。另外,我尝试限制并发编排器和活动函数的数量(请参阅本文档),但这似乎在一定程度上破坏了Azure函数具有可伸缩性的目的。它确实有帮助-我得到的太多连接错误更少了。据推测,如果我继续用较小的数字进行测试,我什至可以消除它,但是,再次看来,这很不合理,并且可能还有另一种解决方案。

如何在不增加连接数的情况下将PostgreSQL与Azure函数一起使用?

Har*_*ran 0

这是Dependency Injection真正有帮助的地方。您可以创建一个singleton客户端,它会完美地完成工作。如果您想了解有关使用寿命的更多信息,可以在文档中阅读

  1. 首先添加这个nugetMicrosoft.Azure.Functions.Extensions.DependencyInjection

  2. 现在添加一个如下所示的新类并解析您的客户。

[assembly: FunctionsStartup(typeof(Kovai.Serverless360.Functions.Startup))]

namespace MyFunction
{
    class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            ResolveDependencies(builder);
        }
    }
    public void ResolveDependencies(IFunctionsHostBuilder builder)
    {
        var conStr = Environment.GetEnvironmentVariable("PostgresConnectionString");
        builder.Services.AddSingleton((s) =>
        {
            return new NpgsqlConnection(conStr);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以轻松地从任何函数中使用它

public FunctionA
    {
        private readonly NpgsqlConnection _connection;
        public FunctionA(NpgsqlConnection conn)
        {
            _connection = conn;
        }

        public async Task<HttpResponseMessage> Run()
        {
            //do something with your _connection
        }
    }
Run Code Online (Sandbox Code Playgroud)