从 .NET 6.0 升级到 .NET 8.0 后,我在 AWS 上托管的应用程序遇到了问题。我的应用程序正在 Docker 容器中运行。
升级后,我在尝试连接到我的 AWS PostgreSQL 数据库时开始收到以下错误:
FATAL: remaining connection slots are reserved for non-replication superuser connections
环境:AWS RDS PostgreSQL、Docker 容器(生产)
所做的更改:我所做的唯一更改是:
从.NET 6.0升级到.NET 8.0。
更新了 Dockerfile 以反映新的 .NET 版本。
我没有更改应用程序代码或数据库连接设置中的任何其他内容。升级前应用程序运行顺利。
使用新配置在本地测试应用程序,但没有遇到相同的连接问题。
为什么仅在升级 .NET 版本时进行的更改就会出现此连接问题? .NET 8.0 中是否有某些内容可能会影响连接的管理方式?
任何见解或建议将不胜感激!
出现此问题是因为我在每个 DbContext 中创建一个新的 NpgsqlDataSource 实例,导致与我的 AWS PostgreSQL 数据库的连接过多。
最初,我的配置如下:
builder.Services.AddDbContext<MasterDbContext>(options =>
{
var dataSource = new NpgsqlDataSourceBuilder( builder.Configuration.GetConnectionString(nameof(MasterDbContext))! ).EnableDynamicJson().Build();
options.UseNpgsql(dataSource);
});
builder.Services.AddDbContext<SlaveDbContext>(options =>
{
var dataSource = new NpgsqlDataSourceBuilder(
builder.Configuration.GetConnectionString(nameof(SlaveDbContext))!).EnableDynamicJson().Build();
options.UseNpgsql(dataSource);
});
通过此设置,DbContext 的每个实例都会创建一个新的 NpgsqlDataSource,从而快速耗尽可用的连接插槽。
为了在启用动态 JSON 支持的同时解决此问题,我转而对 NpgsqlDataSource 实例使用键控单例。以下是我的实现方式:
我将 NpgsqlDataSource 注册为键控单例,以确保只创建一个实例:
builder.Services.AddKeyedSingleton<NpgsqlDataSource>("Master", serviceProvider =>
{
var connectionString = builder.Configuration.GetConnectionString(nameof(MasterDbContext));
return new NpgsqlDataSourceBuilder(connectionString)
.EnableDynamicJson()
.Build();
});
builder.Services.AddKeyedSingleton<NpgsqlDataSource>("Slave", serviceProvider =>
{
var connectionString = builder.Configuration.GetConnectionString(nameof(SlaveDbContext));
return new NpgsqlDataSourceBuilder(connectionString)
.EnableDynamicJson()
.Build();
});
我更新了 DbContext 注册以利用这些键控服务:
builder.Services.AddDbContext<MasterDbContext>((serviceProvider, options) =>
{
var dataSource = serviceProvider.GetRequiredKeyedService<NpgsqlDataSource>("Master");
options.UseNpgsql(dataSource);
});
builder.Services.AddDbContext<SlaveDbContext>((serviceProvider, options) =>
{
var dataSource = serviceProvider.GetRequiredKeyedService<NpgsqlDataSource>("Slave");
options.UseNpgsql(dataSource);
});
这种方法使我能够在 Npgsql 上启用动态 JSON 支持,同时更有效地管理数据库连接,解决 .NET 升级后出现的错误。