web-dev-qa-db-fra.com

Les connexions Azure Sql actives dépassent la limite du pool de connexions

Nous combattons le problème en production de temps en temps, les performances de notre base de données Azure SQL se dégradent considérablement. Nous savons que nous avons des verrous sur l'une des tables, mais ces verrous ne sont pas des interblocages, ce sont de longs verrous et en une heure environ, les performances reviennent à la normale. Nous essayons de trouver tous les scénarios possibles sur la façon dont nous obtenons ces longs verrous (chaque requête est super rapide et tous les analyseurs de performances pourraient nous montrer ce qui cause les longs verrous). La raison de cette question est l'image ci-dessous:

enter image description here

Les paramètres du pool de connexions sortantes ne permettent de regrouper que 200 connexions. Et la plupart du temps, nous avons environ 10 à 20 connexions ouvertes/regroupées avec la base de données. Puis soudain, un certain nombre de connexions actives commencent à se développer et le pool est complètement pris. Bien qu'un certain nombre de connexions groupées restent inférieures à 200, nous constatons un certain nombre de connexions actives utilisant sp_who2 atteindre les connexions 1,5k-2k (parfois 4k-5k).

J'ai créé le même graphique à l'aide des outils de surveillance Azure Portal. Il a une période d'agrégation différente mais présente le même problème: enter image description here

la chaîne de connexion que nous utilisons:

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 Taille = 200; Pooling = True; App = [AppName]

Comment est-ce possible compte tenu de la limitation du pool de connexions à 200 connexions?

ps: il n'y a pas de tâche périodique, de requête longue ou d'autre outil qui fait quoi que ce soit, nous avons vérifié avec sp_who2 toutes les connexions actives à la base de données.

12
Alexey Strakh

[c'est plus un long commentaire qu'une réponse]

J'ai plusieurs hôtes connectés à la même base de données, mais chaque hôte a la même limitation de 200 connexions

Le pool de connexions est par (Chaîne de connexion, AppDomain). Chaque serveur peut avoir plusieurs AppDomains. Et chaque AppDomain aura un pool de connexions par chaîne de connexion. Donc, ici, si vous avez différents combos utilisateur/mot de passe, ils généreront différents pools de connexions. Donc pas de vrai mystère pourquoi il est possible d'avoir plus de 200 connexions.

Alors, pourquoi obtenez-vous beaucoup de connexions? Causes possibles:

Fuites de connexion.

Si vous ne parvenez pas à supprimer un DbContext ou un SqlConnection, cette connexion persistera sur le tas géré jusqu'à sa finalisation et ne sera pas disponible pour une réutilisation. Lorsqu'un pool de connexions atteint sa limite, une nouvelle demande de connexion attend 30 secondes pour qu'une connexion devienne disponible et échoue par la suite.

Vous ne verrez aucune attente ou blocage sur le serveur dans ce scénario. Les sessions seront toutes inactives, pas en attente. Et il n'y aurait pas un grand nombre de demandes dans

select *
from sys.dm_exec_requests 

Notez que les statistiques d'attente de session sont désormais disponibles sur Azure SQL DB, il est donc beaucoup plus facile de voir les blocages et les attentes en temps réel.

select *
from sys.dm_exec_session_wait_stats

Blocage.

Si les demandes entrantes commencent à être bloquées par une transaction et que de nouvelles demandes continuent de démarrer, votre nombre de sessions peut augmenter, car les nouvelles demandes obtiennent de nouvelles sessions, démarrent des demandes et deviennent bloquées. Ici, vous verrez de nombreuses demandes bloquées dans

select *
from sys.dm_exec_requests

Requêtes lentes.

Si les demandes parlaient juste longtemps pour se terminer en raison de la disponibilité des ressources (CPU, disque, journal), vous pouvez le voir. Mais c'est peu probable car votre utilisation de DTU est faible pendant cette période.

La prochaine étape consiste donc à voir si ces connexions sont actives sur le serveur suggérant un blocage ou inactives sur le serveur suggérant un problème de pool de connexions.

Il y a 2 choses que vous pouvez vérifier sur vos objets dbcontext pour voir si vous les utilisez correctement et éliminer l'objet pour renvoyer la connexion au pool de connexions.

Tout d'abord, vous créez le dbcontext à partir du code. Vérifiez s'il existe une instruction using autour de chaque étendue de création de l'objet dbcontext. Quelque chose comme:

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

Cela éliminera le contexte lorsqu'il sort automatiquement du champ d'application.

Deuxièmement, vous utilisez l'injection de dépendances pour injecter l'objet dbcontext. Assurez-vous que vous utilisez la portée:

services.AddScoped<xxxContext>(

La DI se chargera ensuite de disposer vos objets de contexte.

La prochaine chose que vous pouvez vérifier est si vous avez des transactions non engagées. Vérifiez si toutes vos transactions se trouvent dans des blocs, afin qu'elles soient validées ou annulées lorsque vous êtes hors de portée.

2
Peter

Le problème peut être lié à " Fragmentation du pool "

La fragmentation des pools est un problème courant dans de nombreuses applications Web où l'application peut créer un grand nombre de pools qui ne sont pas libérés jusqu'à la fin du processus. Cela laisse un grand nombre de connexions ouvertes et consomme de la mémoire, ce qui entraîne de mauvaises performances.

Fragmentation du pool en raison de la sécurité intégrée * Les connexions sont regroupées en fonction de la chaîne de connexion plus l'identité de l'utilisateur. Par conséquent, si vous utilisez l'authentification de base ou l'authentification Windows sur le site Web et une connexion de sécurité intégrée, vous obtenez un pool par utilisateur. Bien que cela améliore les performances des demandes de base de données suivantes pour un seul utilisateur, cet utilisateur ne peut pas tirer parti des connexions établies par d'autres utilisateurs. Il en résulte également au moins une connexion par utilisateur au serveur de base de données. Il s'agit d'un effet secondaire d'une architecture d'application Web particulière que les développeurs doivent évaluer par rapport aux exigences de sécurité et d'audit.

Source : https://docs.Microsoft.com/en-us/dotnet/framework/data/adonet/sql-server- connexion-pooling

1
Shailendra