Ця стаття є дзеркальною статтею машинного перекладу, будь ласка, натисніть тут, щоб перейти до оригінальної статті.

Вид: 24272|Відповідь: 0

[Джерело] EF Core pit: DbContextPool спричиняє вичерпання з'єднання пулу з'єднань з базою даних

[Копіювати посилання]
Опубліковано 2019-11-18 14:41:59 | | |
DbContextPool — це нова функція, введена в ASP.NET Core 2.1, яка економить витрати на створення інстансу DbContext, але в ній прихована невелика яма.
Нещодавно проєкт ASP.NET Core працював безперервно протягом певного часу, після чого в журналах з'явилася помилка, що пул підключень до бази даних досяг максимальної кількості з'єднань:


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.
   на System.Data.Common.ADP.ExceptionWithStackTrace(Exception e)
Спочатку я думав, що це якийсь код, який змушує DbContext правильно утилізуватися, але в коді не знайшов жодних підказок. Пізніше більше не було сумнівів, лише DbContextPool, тож я спробував видалити DbContextPool, але помилка зникла. Це справді було спричинено DbContextPool, але те, що змушує людей задуматися, — це те, що DbContextPool спочатку був призначений для економії витрат на створення екземплярів DbContext, тож як він може споживати більше з'єднань з базою даних, а навантаження цього проєкту дуже низьке, як він може споживати весь пул підключень?
Я говорив про цю дивну проблему на щотижневій зустрічі сьогодні, і раптом подумав, що кожен екземпляр DbContext займатиме з'єднання з базою даних (SqlConnection), і коли DbContextPool не увімкнений, як тільки запит завершиться, відповідний екземпляр DbContext буде видалений, а підключення до бази даних повертається до пулу з'єднань. При використанні DbContextPool DbContext не буде утилізований, а повертається назад у DbContextPool після завершення запиту, а DbContext повертається у власний пул, що означає, що відповідне з'єднання з базою даних не повертається до пулу з'єднань, до якого він належить. Кожен DbContext у DbContextPool відповідає з'єднанню з базою даних, і для кожного додаткового DbContext у DbContextPool буде на одне з'єднання з базою даних менше. Коли два пули різного розміру, а DbContextPool більший за пул з'єднань бази даних, виникає проблема: DbContextPool вільно заповнює DbContext у пул відповідно до розміру власного пулу (припустимо, що він 128), ігноруючи розмір пулу з'єднань базою даних (припускаючи, що він 100), і наведена помилка виникає, коли 101-й DbContext заповнено.
Цей проєкт використовує налаштування за замовчуванням, чи викликає стандартні налаштування цю проблему?

Дивлячись на вихідний код реалізації DbContextPool, обмеження розміру за замовчуванням для пулу виявлення становить 128


Дивлячись на вихідний код реалізації SqlConnention, ви побачите, що за замовчуванням обмеження розміру для пулів з'єднань становить 100

Стандартне налаштування викликає проблему, що насправді є невеликою помилкою.

Знаючи причину, рішення просте — встановити poolSize DbContextPool меншим за Max_Pool_Size пулу з'єднань бази даних





Забити

Кількість учасників1МБ+1 Сприяють+1 Колапс причина
Zmoli775 + 1 + 1 Наступи на яму і наступи на неї +1

Переглянути всі рейтинги





Попередній:C# успадковує визначення IsAssignableFrom, IsSubclassOf
Наступний:Обхідний шлях основного виключення MySQL Entity Framework
Застереження:
Усе програмне забезпечення, програмні матеріали або статті, опубліковані Code Farmer Network, призначені лише для навчання та досліджень; Вищезазначений контент не повинен використовуватися в комерційних чи незаконних цілях, інакше користувачі несуть усі наслідки. Інформація на цьому сайті надходить з Інтернету, і спори щодо авторських прав не мають до цього сайту. Ви повинні повністю видалити вищезазначений контент зі свого комп'ютера протягом 24 годин після завантаження. Якщо вам подобається програма, будь ласка, підтримуйте справжнє програмне забезпечення, купуйте реєстрацію та отримайте кращі справжні послуги. Якщо є будь-яке порушення, будь ласка, зв'яжіться з нами електронною поштою.

Mail To:help@itsvse.com