Прошло довольно много времени с тех пор, как этот пост был впервые поднят, но я недавно столкнулся с этой проблемой в производственной среде и подумал, что она может быть полезна для других в будущем.
У нас есть веб-приложение ASP.NET MVC, работающее в .NET 4.5.2 с балансировкой нагрузки между двумя узлами. Приложение было настроено для хранения сеанса в базе данных ASPState на SQL Server 2012 (версия 11.0.5058.0). Мы страдали от перерывов:
Информация об исключении:
Тип исключения: HttpException
Сообщение об исключении: невозможно подключиться к базе данных сеансов SQL Server.
Тайм-аут истек. Время ожидания истекло до получения соединения из пула. Это могло произойти из-за того, что все пул соединений использовался и был достигнут максимальный размер пула.
Некоторые ответы здесь, касающиеся того, чтобы убедиться, что в кодовой базе нет других утечек соединений, я считаю, ошибочны. Пул соединений создается для каждой отдельной строки соединения, поэтому любые исправления для соединений с другими базами данных не окажут благотворного влияния на базу данных состояния сеанса.
Мы решили это с двумя изменениями:
Увеличение максимального размера пула путем переопределения значения по умолчанию 100 в строке подключения в файле web.config:
sqlConnectionString="data source=SERVERNAME;Initial Catalog=AspState;user id=AspStateUser;password=xxxxx;App=xxxx; Max Pool Size=200;"
Было очевидно, что база данных AspState была создана с помощью командной строки .NET 2.0 и, что важно, у dbo.DeleteExpiredSessions SP есть проблемы с блокировкой. Чтобы еще больше усугубить проблему, задание было настроено на выполнение этой процедуры каждую минуту. База данных AspState была воссоздана с использованием командной строки .NET 4.0 следующим образом:
C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319> aspnet_regsql.exe -ssadd
- sstype c -S НАШЕ НАЗВАНИЕ -D "AspState" -E
Крайне важно, что более поздняя версия включает в себя улучшенную производительность версии процедуры DeleteExpiredSessions, которая включает в себя курсор, который удаляет истекшие сеансы по одному. Мы также изменили график выполнения соответствующего задания для выполнения каждый час, а не каждую минуту.