Denne artikel er en spejling af maskinoversættelse, klik venligst her for at springe til den oprindelige artikel.

Udsigt: 24272|Svar: 0

[Kilde] EF Core-pit: DbContextPool forårsager udtømning af databaseforbindelsespoolen

[Kopier link]
Opslået den 18-11-2019 14:41:59 | | |
DbContextPool er en ny funktion, der blev introduceret i ASP.NET Core 2.1, som sparer overhead ved at oprette en DbContext-instans, men der er en lille grube skjult i den.
For nylig kørte et ASP.NET Core-projekt kontinuerligt i en periode, og så dukkede der en fejl op i logfilerne, der viste, at databaseforbindelsespuljen nåede det maksimale antal forbindelser:


System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
   på System.Data.Common.ADP.ExceptionWithStackTrace(Exception e)
Først troede jeg, det var en kode, der fik DbContexten til at blive bortskaffet korrekt, men jeg fandt ingen spor i koden. Senere var der egentlig ikke mere at tvivle på, kun DbContextPool, så jeg prøvede at fjerne DbContextPool, men fejlen forsvandt. Det blev faktisk forårsaget af DbContextPool, men det, der får folk til at undre sig, er, at DbContextPool oprindeligt var tiltænkt at spare overhead ved at oprette DbContext-instanser, så hvordan kan det forbruge flere databaseforbindelser, og belastningen på dette projekt er meget lav, hvordan kan det så forbruge hele forbindelsespuljen?
Jeg talte om dette mærkelige problem på det ugentlige møde i dag, og pludselig tænkte jeg, at hver DbContext-instans vil optage en databaseforbindelse (SqlConnection), og når DbContextPool ikke er aktiveret, vil anmodningen blive kasseret, så snart anmodningen slutter, og databaseforbindelsen vil blive lagt tilbage i forbindelsespoolen. Når DbContextPool bruges, vil DbContext ikke blive bortskaffet, men vil blive placeret tilbage i DbContextPool, når anmodningen er afsluttet, og DbContext vil blive placeret tilbage i sin egen pool, hvilket betyder, at dens tilsvarende databaseforbindelse ikke vil blive returneret til den forbindelsespulje, den tilhører. Hver DbContext i DbContextPool svarer til en databaseforbindelse, og for hver yderligere DbContext i DbContextPool vil der være én mindre databaseforbindelse i databaseforbindelsespoolen. Når de to pools har forskellige størrelser, og DbContextPool er større end databaseforbindelsespoolen, opstår problemet: DbContextPool fylder frit DbContexten ind i poolen i henhold til størrelsen af sin egen pool (lad os sige, at den er 128), ignorerer størrelsen af databaseforbindelsespoolen (forudsat at den er 100), og ovenstående fejl vil opstå, når den 101. DbContext er fyldt.
Dette projekt bruger standardindstillinger, udløser standardindstillingen dette problem?

Når man ser på DbContextPool-implementeringskildekoden, er standardstørrelsesgrænsen for discovery poolen 128


Hvis du kigger på SqlConnentions implementeringskildekode, vil du opdage, at standardstørrelsesgrænsen for forbindelsespools er 100

Standardindstillingen vil udløse problemet, hvilket virkelig er en lille faldgrube.

Når man kender grunden, er løsningen enkel: sæt poolSize af DbContextPool til mindre end Max_Pool_Size af databaseforbindelsespoolen





Score

Antal deltagere1MB+1 bidrage+1 Sammenbrud årsag
Zmoli775 + 1 + 1 Træd på pitten og træd på den +1

Se alle vurderinger





Tidligere:C# arver bestemmelsen af IsAssignableFrom, IsSubclassOf
Næste:MySQL Entity Framework Core undtagelsesløsning
Ansvarsfraskrivelse:
Al software, programmeringsmaterialer eller artikler udgivet af Code Farmer Network er kun til lærings- og forskningsformål; Ovenstående indhold må ikke bruges til kommercielle eller ulovlige formål, ellers skal brugerne bære alle konsekvenser. Oplysningerne på dette site kommer fra internettet, og ophavsretstvister har intet med dette site at gøre. Du skal slette ovenstående indhold fuldstændigt fra din computer inden for 24 timer efter download. Hvis du kan lide programmet, så understøt venligst ægte software, køb registrering og få bedre ægte tjenester. Hvis der er nogen overtrædelse, bedes du kontakte os via e-mail.

Mail To:help@itsvse.com