Entity Framework Core оставляет многие соединения в спящем состоянииC#

Место общения программистов C#
Ответить
Anonymous
 Entity Framework Core оставляет многие соединения в спящем состоянии

Сообщение Anonymous »

У меня есть API .NET Core, использующий Entity Framework Core. Контекст БД регистрируется в Startup.cs следующим образом:

Код: Выделить всё

services.AddDbContext(options =>
options.UseSqlServer(connectionString,
providerOptions => providerOptions.CommandTimeout(60)));
В строке подключения я установил

Код: Выделить всё

Pooling=true;Max Pool Size=100;Connection Timeout=300
Контроллер вызывает методы в службе, которая, в свою очередь, вызывает асинхронные методы в репозитории для извлечения и обработки данных.
Все работало бы хорошо, если бы количество одновременных пользователей меньше 500 во время нагрузочного тестирования. Однако за пределами этого числа я начинаю видеть множество ошибок с истекшим тайм-аутом. Когда я проверил базу данных, тупиковой ситуации не было, но я увидел более 100 подключений в спящем режиме (API размещен на двух модулях Kubernetes). Я отслеживал эти соединения во время тестирования, и оказалось, что вместо повторного использования текущих спящих соединений в пул добавлялись новые. Насколько я понимаю, ядро ​​Entity Framework управляет открытием и закрытием соединений, но, похоже, это не так. Или я что-то упускаю?
Ошибка выглядит так:

Код: Выделить всё

{ "StatusCode":500,"Message":"Error:Timeout expired.
The timeout period elapsed prior to obtaining a connection from the pool.c
This may have occurred because all pooled connections were in use and max pool size was reached.
Stack Trace:
at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides)
at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides)
at Microsoft.Data.SqlClient.SqlConnection.Open()
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternal(Boolean errorsExpected)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.BeginTransaction(IsolationLevel isolationLevel)
...
Пример использования DbContext:
контроллер вызывает метод в классе обслуживания:

Код: Выделить всё

var result = await _myservice.SaveUserStatusAsync(userId, status);
затем в «myservice»:

Код: Выделить всё

var user = await _userRepo.GetUserAsync(userId);
....установите статус пользователя на новое значение, а затем

Код: Выделить всё

return await _userRepo.UpdateUserAsync(user);
затем в 'userrepo':

Код: Выделить всё

_context.user.Update(user);
var updated = await _context.SaveChangesAsync();
return updated > 0;
Обновление:
Большое спасибо Ивану Янгу, который щедро предложил награду. Хотя я все еще занимаюсь расследованием, я многому научился, прочитав все комментарии и ответы ниже. Вот что я пробовал до сих пор: я увеличил размер пула до 200 (я знаю, что это неправильный способ решения проблемы), увеличил количество модулей, чтобы API теперь работал на 4 модулях, и выделил больше памяти. к каждому поду. Конечный результат до сих пор был хорошим: 500 ошибок полностью исчезли при одновременном использовании до 2000 пользователей. Я обновлю этот вопрос своими выводами после того, как попробую другие варианты.

Подробнее здесь: https://stackoverflow.com/questions/687 ... ing-status
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»