PostgreSQL:负载测试引发错误 - Npgsql.PostgresException:'53300:抱歉,客户端已经太多了'

Posted

技术标签:

【中文标题】PostgreSQL:负载测试引发错误 - Npgsql.PostgresException:\'53300:抱歉,客户端已经太多了\'【英文标题】:PostgreSQL: Load testing throws error - Npgsql.PostgresException: '53300: sorry, too many clients already'PostgreSQL:负载测试引发错误 - Npgsql.PostgresException:'53300:抱歉,客户端已经太多了' 【发布时间】:2020-09-21 08:44:02 【问题描述】:

我有一个简单的代码尝试为我的 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: sorry, too many clients already'

数据库连接类

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 所以我的问题是这是正常的还是有什么做错需要纠正,如果是这样,我该如何纠正 谢谢

【问题讨论】:

“负载测试”相当模糊。如果您试图测试 max_connections 在负载下执行它应该执行的操作,那么您就成功了。如果您尝试做其他事情,您需要告诉我们那是什么。 我的问题是可以避免 Npgsql.PostgresException: '53300: sorry, too many clients already' 异常吗? 是的,要么降低线程数,要么提高 max_connections。哪个更好取决于您要做什么,这仍然是一个谜。 感谢 jjanesso 如果我有超过一千个并发用户,我还需要将 max_connections 提高到这个数量吗?这是个好主意吗? @Medard 不,不要忘记阅读时间。 100 个并发用户可能同时进行 10 个查询。如果查询很短,您可以使用单个连接,因为连接请求将排队(最多 timeout 秒) 【参考方案1】:

如果您执行的查询很短(即完成时间不到 60 秒),您不应该看到这种行为。

当达到最大连接数(最大池大小)并且您要求更多时,npgsql 将等待最多 timeout(在您的情况下为 60 秒,默认为 15)返回一个。它不会建立更多,但它会等待另一个连接停止使用并返回到池中。

在您的示例中,您同时启动了 200 个线程。前 100 个应该没有问题,接下来的 100 个应该等待前 100 个将连接返回到池中,然后可以建立/使用它们的连接。

因此,您正在运行的查询非常长(超过 60 秒),或者您在完成后未能关闭连接。我没有看到任何 close 语句,因此您依赖于连接 dispose,但这是自定义代码...并且您的自定义 dispose() 必须显式关闭(或处置)底层连接。

【讨论】:

以上是关于PostgreSQL:负载测试引发错误 - Npgsql.PostgresException:'53300:抱歉,客户端已经太多了'的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Locust 负载测试工具中获得详细的错误报告?

将包含对象数组的 json 传递给 PostgreSQL 函数会引发格式错误的数组文字。意外的数组元素

GitLab 触发“脑裂”问题,5 台 PostgreSQL 3 台彻底趴下

一条SQL引发系统out of memory PostgreSQL

在 Azure 应用服务上运行的 ASP.NET Core 3.1 应用针对 1.6 MB json 有效负载引发 EPIPE 错误

案例SSO支持负载均衡引发的A5单点登录实现问题