Tento článek je zrcadlovým článkem o strojovém překladu, klikněte zde pro přechod na původní článek.

Pohled: 24272|Odpověď: 0

[Zdroj] EF Core pit: DbContextPool způsobuje vyčerpání spojení databázového poolu

[Kopírovat odkaz]
Zveřejněno 18. 11. 2019 14:41:59 | | |
DbContextPool je nová funkce zavedená v ASP.NET Core 2.1, která šetří režijní zátěž při vytváření instance DbContext, ale je v ní skrytá malá jáma.
Nedávno běžel nepřetržitě projekt ASP.NET Core po určitou dobu a poté se v logech objevila chyba, že databázový pool připojení dosáhl maximálního počtu připojení:


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)
Nejdřív jsem si myslel, že je to nějaký kód, který způsobuje správné likvidace DbContextu, ale v kódu jsem žádné stopy nenašel. Později už nebylo o čem pochybovat, jen DbContextPool, takže jsem se pokusil DbContextPool odstranit, ale chyba zmizela. Bylo to skutečně způsobeno DbContextPool, ale co lidi nutí k otázce, je fakt, že DbContextPool byl původně určen k úspoře režie při vytváření instancí DbContextu, takže jak může spotřebovávat více databázových připojení a zátěž tohoto projektu je velmi nízká, jak může spotřebovávat celý pool připojení?
O tomto zvláštním problému jsem dnes mluvil na týdenní schůzce a pak jsem najednou napadl, že každá instance DbContext bude zabírat připojení k databázi (SqlConnection), a když DbContextPool není povolen, jakmile požadavek skončí, příslušná instance DbContext bude odstraněna a připojení k databázi se vrátí zpět do poolu připojení. Při použití DbContextPool nebude DbContext vyřazen, ale po skončení požadavku bude vrácen zpět do DbContextPoolu a DbContext bude vrácen do vlastního poolu, což znamená, že jeho odpovídající databázové spojení nebude vráceno do poolu spojení, do kterého patří. Každý DbContext v DbContextPool odpovídá databázovému spojení a pro každý další DbContext v DbContextPool bude o jedno databázové spojení méně v databázovém poolu. Když jsou oba pooly různých velikostí a DbContextPool je větší než databázový connection pool, problém nastává, DbContextPool volně vyplní DbContext do poolu podle velikosti svého vlastního poolu (řekněme, že je 128), přičemž ignoruje velikost databázového connection poolu (za předpokladu, že je 100), a výše uvedená chyba nastane, když je 101. DbContext naplněn.
Tento projekt používá výchozí nastavení, spouští výchozí nastavení tento problém?

Při pohledu na zdrojový kód implementace DbContextPool je výchozí limit velikosti pro discovery pool 128


Při pohledu na zdrojový kód implementace SqlConnention zjistíte, že výchozí limit velikosti pro pooly připojení je 100

Výchozí nastavení spustí problém, což je vlastně malá past.

S ohledem na důvod je řešení jednoduché: nastavte velikost poolSize DbContextPool na menší než Max_Pool_Size poolu připojení k databázi





Partitura

Počet účastníků1MB+1 přispět+1 Zhroucení důvod
Zmoli775 + 1 + 1 Šlápni na jámu a šlápni na něj +1

Zobrazit všechna hodnocení





Předchozí:C# dědí určení IsAssignableFrom, IsSubclassOf
Další:Řešení výjimek Core v MySQL Entity Framework
Zřeknutí se:
Veškerý software, programovací materiály nebo články publikované organizací Code Farmer Network slouží pouze k učení a výzkumu; Výše uvedený obsah nesmí být používán pro komerční ani nelegální účely, jinak nesou všechny důsledky uživatelé. Informace na tomto webu pocházejí z internetu a spory o autorská práva s tímto webem nesouvisí. Musíte výše uvedený obsah ze svého počítače zcela smazat do 24 hodin od stažení. Pokud se vám program líbí, podporujte prosím originální software, kupte si registraci a získejte lepší skutečné služby. Pokud dojde k jakémukoli porušení, kontaktujte nás prosím e-mailem.

Mail To:help@itsvse.com