Ta članek je zrcalni članek strojnega prevajanja, kliknite tukaj za skok na izvirni članek.

Pogled: 24272|Odgovoriti: 0

[Vir] EF Core pit: DbContextPool povzroči izčrpanost povezave baze podatkov

[Kopiraj povezavo]
Objavljeno 18. 11. 2019 ob 14:41:59 | | |
DbContextPool je nova funkcija, uvedena v ASP.NET Core 2.1, ki prihrani stroške ustvarjanja DbContext instance, vendar je v njej skrita majhna jama.
Nedavno je projekt ASP.NET Core tekel neprekinjeno določen čas, nato pa se je v dnevnikih pojavila napaka, da je bazen povezav v bazi podatkov dosegel največje število povezav:


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.
   at System.Data.Common.ADP.ExceptionWithStackTrace(Exception e)
Sprva sem mislil, da je neka koda povzročila, da se DbContext pravilno odstrani, vendar v kodi nisem našel nobenih sledi. Kasneje ni bilo več ničesar za dvomiti, le DbContextPool, zato sem poskušal odstraniti DbContextPool, a je napaka izginila. Res ga je povzročil DbContextPool, a kar ljudi sprašuje, je, da je bil DbContextPool prvotno namenjen prihrani stroškov ustvarjanja instanc DbContext, zato kako lahko porabi več povezav z bazo podatkov, in je obremenitev tega projekta zelo majhna, kako lahko porabi celoten bazen povezav?
O tej nenavadni težavi sem danes govoril na tedenskem sestanku, nato pa sem nenadoma pomislil, da bo vsaka instanca DbContext zasedala povezavo z bazo podatkov (SqlConnection), in ko DbContextPool ni omogočen, se takoj po koncu zahteve ustrezna instanca DbContext odstrani, povezava z bazo podatkov pa se vrne v povezovalni bazen. Pri uporabi DbContextPool DbContext ne bo odstranjen, ampak bo po koncu zahteve vrnjen v DbContextPool, DbContext pa se vrne v svoj lasten bazen, kar pomeni, da ustrezna povezava z bazo podatkov ne bo vrnjena v povezovalni bazen, kateremu pripada. Vsak DbContext v DbContextPoolu ustreza povezavi z bazo podatkov, in za vsak dodatni DbContext v DbContextPoolu bo ena povezava z bazo podatkov manj. Ko sta oba bazena različnih velikosti in je DbContextPool večji od povezovalnega bazena podatkovne baze, nastane težava: DbContextPool prosto napolni DbContext v bazen glede na velikost svojega bazena (recimo, da je 128), pri čemer ignorira velikost povezovalnega bazena baze podatkov (ob predpostavki, da je 100), zgornja napaka pa se pojavi, ko je 101. DbContext polnjen.
Ta projekt uporablja privzete nastavitve, ali privzeta nastavitev sproži ta problem?

Če pogledamo izvorno kodo implementacije DbContextPool, je privzeta omejitev velikosti za discovery pool 128


Če pogledate izvorno kodo implementacije SqlConnentiona, boste ugotovili, da je privzeta omejitev velikosti za povezave 100

Privzeta nastavitev sproži težavo, kar je pravzaprav majhna past.

Ker poznamo razlog, je rešitev preprosta: nastavite velikost bazena DbContextPool na manjšo od Max_Pool_Size bazena povezav z bazo podatkov





Partitura

Število udeležencev1MB+1 prispevati+1 Propad razlog
Zmoli775 + 1 + 1 Stopi na jamo in stopi nanjo +1

Oglejte si vse ocene





Prejšnji:C# podeduje določitev IsAssignableFrom, IsSubclassOf
Naslednji:Rešitev za izjeme MySQL Entity Framework Core
Disclaimer:
Vsa programska oprema, programski materiali ali članki, ki jih izdaja Code Farmer Network, so namenjeni zgolj učnim in raziskovalnim namenom; Zgornja vsebina ne sme biti uporabljena v komercialne ali nezakonite namene, sicer uporabniki nosijo vse posledice. Informacije na tej strani prihajajo z interneta, spori glede avtorskih pravic pa nimajo nobene zveze s to stranjo. Zgornjo vsebino morate popolnoma izbrisati z računalnika v 24 urah po prenosu. Če vam je program všeč, podprite pristno programsko opremo, kupite registracijo in pridobite boljše pristne storitve. Če pride do kakršne koli kršitve, nas prosimo kontaktirajte po elektronski pošti.

Mail To:help@itsvse.com