Ngu*_*ong 6 c# postgresql dependency-injection connection-pooling asp.net-core
我正在努力使用, &NpgsqlConnection()中的多个连接字符串注册 DI 。ASP.NET Core 3.1Dapper v2.0.78Postgres v11
我将提供当前状态并修复以下代码:
步骤1。Startup.cs --> ConfigureServices()
services.AddTransient<IDbConnectionFactory, DapperDbConnectionFactory>(sp =>
{
var connectionDict = new Dictionary<DatabaseConnectionName, string>
{
{ DatabaseConnectionName.Cnn1, "Connectionstring 1"},
{ DatabaseConnectionName.Cnn2, "Connectionstring 2"}
};
return new DapperDbConnectionFactory(connectionDict);
});
Run Code Online (Sandbox Code Playgroud)
第2步。DapperDbConnectionFactory看起来像这样:
public class DapperDbConnectionFactory : IDbConnectionFactory
{
private readonly IDictionary<DatabaseConnectionName, string> _connectionDict;
public DapperDbConnectionFactory(IDictionary<DatabaseConnectionName, string> connectionDict)
{
_connectionDict = connectionDict;
}
public IDbConnection CreateDbConnection(DatabaseConnectionName connectionName)
{
string connectionString = null;
if (_connectionDict.TryGetValue(connectionName, out connectionString))
{
return new NpgsqlConnection(connectionString); // <--- I think the issue comes from here
}
throw new ArgumentNullException();
}
}
Run Code Online (Sandbox Code Playgroud)
第三步:我使用这段代码的方式:
public ConstructorMedthod(IDbConnectionFactory _connFactory)
{
_conn = _connFactory.CreateDbConnection(DatabaseConnectionName.Cnn1);
}
public async Task<QueryResult<IBaseReportModel>> Handle(...)
{
...
var query = await _conn.QueryMultipleAsync("Query content here"); // <--- I think the issue comes from here
...
}
Run Code Online (Sandbox Code Playgroud)
我确实认为使用方式不正确,至少需要将调用包装_conn.QueryMultipleAsync在using语句中以确保连接已关闭并释放,然后返回连接池。因为DI容器只是管理only的生命周期DapperDbConnectionFactory而不是IDbConnection
结果,有时我会收到此错误:
Npgsql.NpgsqlException (0x80004005):连接池已耗尽,请提高 MaxPoolSize(当前为 100)或超时(当前为 15 秒)
我必须重新启动应用程序然后它才恢复正常。所以我不确定问题是最大连接池还是网络超时。它应该能够检查池中的连接数与当时的最大连接池相比。我假设是这样。
我有两个想法:
将调用包含_conn.QueryMultipleAsync在using声明中。但这样我就必须在调用处改变太多代码_conn。
改成DI的方式(想法来自这里)。更多详细信息如下。
步骤1。Startup.cs --> ConfigureServices()
services.AddTransient<ServiceResolver>(serviceProvider => cnn_Name =>
{
switch (cnn_Name)
{
case "Cnn1":
return new NpgsqlConnection("Connectionstring 1");
case "Cnn2":
return new NpgsqlConnection("Connectionstring 2");
default:
throw new KeyNotFoundException();
}
});
public delegate IDbConnection ServiceResolver(string connectionstring);
Run Code Online (Sandbox Code Playgroud)
第二步:我的使用方式:
private readonly IDbConnection _conn;
public ConstructorMedthod(ServiceResolver serviceAccessor)
{
_conn = serviceAccessor(DbConnectionKey.Cnn1);
}
public async Task<QueryResult<IBaseReportModel>> Handle(...)
{
...
var query = await _conn.QueryMultipleAsync("Query content here");
// Now I suppose the _conn will be closed & disposed by DI container.
...
}
Run Code Online (Sandbox Code Playgroud)
在 ASP.NET Core 3.1 中使用多个连接字符串注册 DINpgsqlConnection的正确方法是什么?postgreSQL
SELECT * FROM pg_stat_activity;
Run Code Online (Sandbox Code Playgroud)
max connection pool大于 100。这是否是最佳实践?我发现这个帖子说的是仅仅增加
max_connections是个坏主意。你也需要增加shared_buffers。kernel.shmmax
但实际上,我使用的是AWS的RDS PostgreSQL。所以我想appsettings这样的配置。
用户ID = root;密码= myPassword;主机= localhost;端口= 5432;数据库= myDataBase;池= true;最小池大小= 0;
Maximum Pool Size=200;
此外,正如这篇文章所说
Npgsql connection pooling is implemented inside your application process - it has nothing to do with PostgreSQL,这是完全没有意识到的。
所以我很困惑PostgreSQL(问题#2)和Appsettings(问题#3)之间的最大连接池
不幸的是,当前状态解决方案的作者说
我不确定我是否正确使用了最佳实践,但我这样做是为了处理多个连接字符串。
详细阅读评论后,我认识到您必须使用using这样的声明。
public async Task<QueryResult<IBaseReportModel>> Handle(...)
{
...
using(var conn = _connFactory.CreateDbConnection(DatabaseConnectionName.Cnn1))
{
var response = await conn.QueryMultipleAsync("Query content here");
}
...
}
Run Code Online (Sandbox Code Playgroud)
否则,你会得到这个错误
Npgsql.NpgsqlException (0x80004005):连接池已耗尽,请提高 MaxPoolSize(当前为 100)或超时(当前为 15 秒)
或者
“53300:剩余的连接插槽保留用于非复制超级用户连接”
突出显示的评论如下。希望它能帮助大家避免隐藏的错误。
更新 - 2022-05-13
从@Shay Rojansky 的回答中,我们已经澄清了混淆-和之间的问题 #3Appsetings -> Maximum Pool Size=200;PostgreSQL --> SHOW max_connections;
| 归档时间: |
|
| 查看次数: |
15009 次 |
| 最近记录: |