活动Azure Sql连接超出了连接池限制

我们的Azure SQL数据库性能会在很长一段时间内显着降低,我们会在生产中解决问题。 我们知道我们在其中一个表上有锁,但是这些锁不是死锁,它们是长锁,并且在一个小时左右的时间内性能恢复正常。 我们正试图找到关于如何获得这些长锁的所有可能场景(每个查询都超快,所有性能分析器都可以向我们展示导致长锁的原因)。 这个问题的原因如下图所示:

在此处输入图像描述

Out连接池设置仅允许汇集200个连接。 大多数时候,我们与数据库有大约10-20个开放/池化连接。 然后突然有许多活动连接开始增长,并且池完全被占用。 虽然许多池化连接保持在200以下,但我们看到使用sp_who2的多个活动连接达到1.5k-2k连接(有时为4k-5k)。

我使用Azure门户监控工具构建了相同的图表。 它有不同的聚合期,但显示相同的问题: 在此处输入图像描述

我们使用的连接字符串:

Data Source = [server] .database.windows.net; initial catalog = [database]; persist security info = True; user id = [user]; password = [password]; MultipleActiveResultSets = True; Connection Timeout = 30; Max Pool大小= 200;池=真;应用= [AppName的]

考虑到200个连接的连接池限制,这怎么可能?

ps:没有周期性任务,长时间运行的查询或其他任何工具,我们检查sp_who2sp_who2所有活动连接。

[这是一个长期评论而非答案]

我确实有几个主机连接到同一个数据库,但每个主机具有相同的200个连接限制

连接池是per(连接字符串,AppDomain)。 每个服务器可能有多个AppDomain。 每个AppDomain每个连接字符串都有一个连接池。 所以,如果您有不同的用户/密码组合,它们将生成不同的连接池。 所以没有真正的谜,为什么有200多个连接可能。

那你为什么要得到很多联系呢? 可能的原因:

连接泄漏。

如果您未能处理DbContext或SqlConnection,那么连接将在托管堆上停留,直到最终完成,并且无法重用。 当连接池达到其限制时,新连接请求将等待30秒以使连接可​​用,并在此之后失败。

在这种情况下,您不会在服务器上看到任何等待或阻塞。 会议将全部闲置,而不是等待。 并且不会有大量的请求

 select * from sys.dm_exec_requests 

请注意,会话等待统计信息现在可以在Azure SQL DB上运行,因此可以更轻松地查看实时阻止和等待。

 select * from sys.dm_exec_session_wait_stats 

阻塞。

如果传入请求开始被某个事务阻止,并且新请求一直在启动,则会话数量会增加,因为新请求会获得新会话,启动请求并被阻止。 在这里你会看到很多被阻止的请求

 select * from sys.dm_exec_requests 

慢查询。

如果请求只是由于资源可用性(CPU,磁盘,日志)而需要很长时间才能完成,您可以看到这一点。 但这不太可能,因为在此期间您的DTU使用率很低。

因此,下一步是查看这些连接是否在服务器上处于活动状态,表明在服务器上阻塞或空闲,表明存在连接池问题。

有两件事可以检查dbcontext对象,看看你是否正确使用它们并配置对象以返回连接池的连接。

首先,您是从代码创建dbcontext。 检查dbcontext对象的每个创建范围周围是否有using语句。 就像是:

 using (var context = new xxxContext()) { ... } 

当它自动超出范围时,这将处理上下文。

其次,您使用dependency injection来注入dbcontext对象。 确保使用作用域:

 services.AddScoped( 

然后DI将负责处理您的上下文对象。

您可以检查的下一件事是您是否有未提交的事务。 检查所有事务是否都在使用块中,因此当您超出范围时,它们将提交或回滚。