我有一个简单的代码试图模拟Postgres数据库的负载测试
List<Values> values = new List<Values>();
for (int i = 0; i < 200; i++)
{
var mythread = new Thread(() =>
{
DatabaseConnection db = new DatabaseConnection();
using (var conn = db.GetDatabaseConnection())
{
var cmd = new NpgsqlCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT val.id, val.name FROM val.myvalue val";
cmd.Prepare();
var reader = cmd.ExecuteReader();
try
{
while (reader.Read())
{
Values value = new Values();
value.Id = reader.GetInt64(0);
value.Name = reader.GetString(1);
values.Add(value);
}
reader.Close();
}
catch (Exception ex)
{
reader.Close();
var exception = ex;
throw exception;
}
}
});
mythread.Start();
}
但是当我运行这个程序时,我得到了错误Npgsql.PostgresException:'53300:对不起,太多客户机已经“”了
数据库连接类
public class DatabaseConnection
{
public NpgsqlConnection GetDatabaseConnection()
{
var connectionstring = "User ID=myuser;Password=mypassword;Server=localhost;Port=5432;Database=myvaluesdb;Pooling=True;Minimum Pool Size=10;Maximum Pool Size=100;Trust Server Certificate=true;Connection Idle Lifetime=300;keepalive=10;Timeout=60";
NpgsqlConnection connection = null;
try
{
connection = new NpgsqlConnection(connectionstring);
connection.Open();
}
catch (Exception)
{
// try to reconnect
connection = new NpgsqlConnection(connectionstring);
connection.Open();
}
if (connection.State == ConnectionState.Open)
Console.WriteLine("connection status = OPEN");
else
{
var exception = new Exception("could not get DB connection");
throw exception;
}
return connection;
}
}
检查max_connections显示100
因此,我的问题是,这是正常的,还是有什么不对劲的地方需要纠正,如果是的话,我该如何纠正?
谢谢
发布于 2020-09-23 13:56:10
如果您执行的查询很短(即不到60秒即可完成),则不应该看到此行为。
当达到最大连接数(最大池大小)并请求更多连接时,npgsql将等待timeout
(在您的情况下是60秒,默认情况下是15个)返回一个连接。它不会建立更多的连接,但是它会等待另一个连接停止使用并返回到池。
在您的示例中,您可以同时启动200个线程。前100应该没有问题,接下来的100应该等待前100个连接返回到池中,然后才能建立/使用它们的连接。
所以,要么您正在运行的查询非常长(超过60秒),要么您在完成时未能关闭连接。我没有看到任何close
语句,所以您依赖于连接dispose
,但这是自定义代码.而且您的自定义dispose()
必须显式关闭(或释放)底层连接。
https://stackoverflow.com/questions/63988893
复制相似问题