应用程序长时间闲置后,EF Core AddAsync和SaveChangesAsync稍慢

时间:2018-12-29 08:41:20

标签: c# entity-framework-core

我目前正在为我的API做基准测试,我注意到使用EF Core进行的第一次保存操作有点延迟。这种情况是在一段时间不活动之后(例如18个小时),第一次保存操作将花费1.5秒执行,随后最多是100毫秒。下面是代码片段,

         public async Task SaveLog(Log log_item)
         {
              // Set created and updated date/time
              log_item.created = DateTime.UtcNow;
              log_item.updated = DateTime.UtcNow;

              if (!(log_item.Month % 2 == 0))
              // Odd
              {
                  var log_item_odd = log_item.ConvertLogToOdd();
                  await _dbContext.Log_Odd.AddAsync(log_item_odd);
              }
              else
              // Even
              {
                  var log_item_even = log_item.ConvertLogToEven();
                  await _dbContext.Log_Even.AddAsync(log_item_even);
              }

              await _dbContext.SaveChangesAsync();
         }

以下是此操作的执行时间,以及对我捕获的日志执行的后续更新(以毫秒为单位)。

[2018-12-29 06:25:00.199] [ADD_LOG] SaveLog 1556  
[2018-12-29 06:25:01.056] [UPDATE_LOG] UpdateLog 362  
[2018-12-29 06:27:13.652] [ADD_LOG] SaveLog 4  
[2018-12-29 06:27:13.886] [UPDATE_LOG] UpdateLog 9  
[2018-12-29 06:29:01.633] [ADD_LOG] SaveLog 4  
[2018-12-29 06:29:01.846] [UPDATE_LOG] UpdateLog 4  
[2018-12-29 06:56:21.544] [ADD_LOG] SaveLog 53  
[2018-12-29 06:56:21.996] [UPDATE_LOG] UpdateLog 5  
[2018-12-29 07:11:58.813] [ADD_LOG] SaveLog 94  
[2018-12-29 07:11:59.051] [UPDATE_LOG] UpdateLog 5  
[2018-12-29 07:16:12.241] [ADD_LOG] SaveLog 3  
[2018-12-29 07:16:12.639] [UPDATE_LOG] UpdateLog 4 

在一段时间不活动之后,我找不到与EF Core相关的任何东西,需要一些时间才能启动,对此是否有解释? *我正在使用PostgreSQL作为数据库。

感谢您的帮助,谢谢。

1 个答案:

答案 0 :(得分:0)

通常,所有提供程序都有一些实现,可以在一段时间的空闲时间后修剪空闲连接。

第一个命令花费更多的时间来创建和打开连接。接下来的命令将使用池化连接,并且速度更快。然后,在闲置特定时间后,提供程序会修剪池并关闭空闲连接。然后在空闲时间之后的下一个命令需要打开一个连接,这又需要花费时间。

例如,对于NpgsqlConnectorPool中有一个PruneIdleConnectors,它根据NpgsqlConnectionStringBuilder.ConnectionIdleLifetime的值进行清理,该值默认为5分钟。以下是相关的pooling参数:

  • 连接空闲寿命如果所有连接的计数都超过MinPoolSize,则在关闭池中的空闲连接之前要等待的时间(以秒为单位)。从3.1开始。默认为300秒。
  • 连接修剪间隔在尝试修剪超出空闲生存期的空闲连接之前,池要等待多少秒(请参阅ConnectionIdleLifetime)。从3.1开始。默认为10秒。

对于ADO.NET SqlConnection pooling,这次大约是4到8分钟:

在连接池闲置大约4-8分钟后,或者如果连接器检测到与服务器的连接已断开,连接池会将连接从池中删除。

注意:注释中也已经提到过,还有其他一些因素可能会影响首次执行时间,包括DBMS中的EF上下文池和查询执行计划缓存。但通常其中最耗时的是重新打开连接。