【问题标题】:Getting timeout expired. Timeout period elapsed prior to obtaining connection from connection pool with Dapper获取超时已过期。在使用 Dapper 从连接池获取连接之前经过的超时时间
【发布时间】:2021-09-28 15:43:21
【问题描述】:

一个应用程序在从连接池获取连接之前给出了异常超时期限。我使用了下面的代码,这个代码 sn-p 是从不同的并发用户调用的,并且可以有高达 10000 pr.second 的最大命中。我使用 Dapper 从 Azure MS SQL 数据库中获取结果。

public async Task<List<Results>> GetDBResults(string Id, int skip, int take)
{
    var values = new DynamicParameters();
    values.Add("Id", Id);
    values.Add("Skip", skip);
    values.Add("Take", take);        
    using var connection = GetConnection(AppSettingsProvider.TryGet("ConnectionString"));
               
    try
    {
        var sw = Stopwatch.StartNew();
        //connection.Open();
        // QueryAsync is from Dapper
        var dbResult = await connection.QueryAsync<ResponseObject>("SP_name", param: values,
                         commandType: CommandType.StoredProcedure, commandTimeout: Constants.CommandTimeout);
        var result= dbResult?.ToList();
        Console.WriteLine("execution time = {0} seconds\n", sw.Elapsed.TotalSeconds);
        return result;
    }
    finally
    {
        connection.Close();                             
    }
}
       
private SqlConnection GetConnection(string connectionString)
{
    var sqlConnection = new SqlConnection(connectionString);
    return sqlConnection;
}

我知道,“使用”将关闭并释放连接对象,连接正在关闭,但数据库池不能立即用于下一个数据库连接。所以,我在最后一个块中明确关闭了数据库连接。这使我成功地执行了更多并发请求。之后,我收到超时异常。

Connection.Open 由 Dapper 管理,所以代码 sn-p 中没有添加 connection.Open。​​

并发用户超过 200 次点击后,我们遇到了超时问题。

请告诉我解决此问题的方法。

【问题讨论】:

  • 这段代码对我来说看起来很合理。 try/finally 看起来是多余的 - 在这里使用本身应该没问题 - 但是:看起来没什么错误。问题:是否有任何 other 代码打开连接?我想知道这段代码是否是受害者,而不是原因 - 原因是一些没有及时返回连接的other代码。
  • 我们没有任何其他打开的数据库连接

标签: dapper connection-timeout


【解决方案1】:

似乎是一个池耗尽问题;如果您每秒有 10000 个请求,并注意到 default connection pool size is 100,那么 即使其他一切都运行良好(永远不会出现 CPU 饥饿、GC 停顿等),那么您只有 10 毫秒的时间用于“获取” 、执行、释放”循环(因为 100 个连接中的每一个都需要每秒处理 100 个请求才能达到总共 10k/s 的请求)。老实说,即使在具有良好 LAN 的硬件上,这也是相当雄心勃勃的——如果您在云中(“Azure MS SQL”):忘记它(除非您为非常非常高级的服务付费)。您可以尝试增加池的大小,但老实说,我想知道某种重新设计是否适合看这里。您以 为单位测量时间这一事实在此处强调了问题的严重性:

Console.WriteLine("execution time = {0} seconds\n", sw.Elapsed.TotalSeconds);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 2014-01-29
    • 1970-01-01
    • 2010-12-11
    相关资源
    最近更新 更多