Период ожидания истек до получения соединения из пула - PullRequest
9 голосов
/ 29 октября 2009

Наш сайт работает нормально в течение 90% дня, затем в часы пик, когда трафик примерно вдвое тяжелее обычного, все замедляется до ползания. Время загрузки страницы, которое обычно составляет 1 секунду, занимает 30 секунд. Проверяя наши журналы ошибок, похоже, что это может быть проблема пула соединений. У нас есть 3 веб-сервера, подключенные к 1 дБ сервера sql. Сервер SQL летает с 25% -ной загрузкой на всех ядрах.

Я смотрю на счетчик Пользовательских подключений на нашем SQL-сервере и вижу, что во время нашего пика у нас есть 400+ Пользовательских подключений, но в нерабочее время это около 120+.

Я почти уверен, что мы просто используем настройки по умолчанию, которые поставляет MS для работы с нашим пулом приложений. Что я могу сделать, чтобы проверить, является ли проблема пула приложений? Каковы недостатки увеличения размера пула приложений до 1000 (и как мне это сделать?).

Спасибо!

Ответы [ 5 ]

15 голосов
/ 19 января 2011

По моему опыту, есть 3 основных типа таймаутов, которые вы можете получить от SQL Server:

1) InvalidOperationException - Ошибка для клиента получить пул соединения из своего пула до истечения времени ожидания, указанного в командной строке (по умолчанию 15 секунд). Пул клиента имеет максимальный размер, и все пулы подключений используются и остаются в использовании до истечения времени ожидания.

2) SQLException - Тайм-аут соединения. Пул соединений клиента создает новое соединение с базой данных, но база данных не отвечает до истечения времени ожидания, указанного в командной строке (по умолчанию 15 секунд).

3) SQLException - Тайм-аут команды. Соединение было получено, но время, затраченное оператором SQL на выполнение команды, превысило время ожидания, указанное в свойстве CommandTimeout команды (по умолчанию 30 секунд)


Ваши обстоятельства, когда сервер работает нормально до тех пор, пока нагрузка не будет добавлена, походят на случай № 1. Я обнаружил, что тайм-ауты приходят очень быстро - обычно 2 секунды.

Я нашел решение этой проблемы, чтобы увеличить максимальное количество потоков в SQL Server. По умолчанию ноль - пусть SQL Server решит. Я видел случаи, когда полный сервер сидит с небольшим использованием ресурсов, в то время как он ограничивал себя, выделяя слишком мало потоков.

Вы можете увеличить настройку максимального количества потоков с помощью этого transact-sql:

sp_configure 'max worker threads', 8192
go
Reconfigure 

Затем перезапустите службу SQL.

Кстати, вы можете увидеть, сколько потоков в настоящий момент выделено SQL Server с помощью этой команды:

select sum(current_workers_count) from sys.dm_os_schedulers

Этот параметр потоков имеет огромное значение для работы SQL Server при многих подключениях. SQL Server перестает отвечать на запросы, если у него заканчиваются потоки.

7 голосов
/ 29 октября 2009

Это может быть связано с неправильным удалением SQL-соединений (возвращаемых в пул). Убедитесь, что вы звоните SqlConnection.Dispose.

5 голосов
/ 29 октября 2009

Это может быть связано с тем, что пул соединений SQL исчерпан (это отличается от пула приложений.) Вы можете проверить это, увеличив размер пула через строку подключения:

Integrated Security=SSPI;Initial Catalog=northwind;Max Pool Size=100;

Но, скорее всего, ваша база данных не успевает за потоком входящих запросов. Это приводит к тому, что соединения ожидают завершения запроса. Добавление большего количества соединений поможет против пакетных запросов, но не против устойчивого большого трафика.

Вот несколько советов по повышению производительности вашего SQL Server при постоянной высокой нагрузке:

  • Сбросить аппаратное обеспечение при проблеме (особенно ОЗУ на SQL Server)
  • Присоедините SQL Server Profiler к серверу, получите трассировку одного периода высокой нагрузки и следуйте предложенным индексам
  • Из журнала трассировки изучайте долго выполняющиеся запросы и улучшайте их вместе с разработчиком T-SQL

Удачи, эти вещи могут быть довольно сложными!

1 голос
/ 11 июля 2017

У меня была эта проблема с Powershell и параллельными запросами ( invoke-sqlcmd , за которым следует еще один invoke-sqlcmd ). Оба запроса включали изменения данных. Решено добавлением -connectiontimeout 1 к вызову параметра.

Пример:

invoke-sqlcmd "insert into testdb..tab1 (cname) select 'x'" -connectiontimeout 1
invoke-sqlcmd "update testdb..tab1 set ctr=ctr+1 where cname='aaa'"

Время ожидания может варьироваться в зависимости от количества затронутых строк.

1 голос
/ 24 августа 2011

Когда я получил эту ошибку:

Период ожидания истек до получения соединения от бассейн. Это могло произойти, потому что все соединения в пуле были в использование и максимальный размер пула были достигнуты

Это было связано с тем, что я использовал SqlCommand.ExecuteQuery() метод вместо SqlCommand.ExecuteNonQuery().

Например: мой исходный сохраненный вызов procdure выглядит примерно так:

using (SqlCommand cmd = new SqlCommand())
{
    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    cmd.CommandText = "InsertSproc";
    cmd.Parameters.AddWithValue("@Value", myValue);
    cmd.Parameters.AddWithValue("@LoggedDate", myDate);
    DatabaseManager.instance.ExecuteQuery(cmd);
}

Код выше - это то, что вызвало исключение. Однако изменение вызова для использования ExecuteNonQuery () решило проблему:

using (SqlCommand cmd = new SqlCommand())
{
    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    cmd.CommandText = "InsertSproc";
    cmd.Parameters.AddWithValue("@Value", myValue);
    cmd.Parameters.AddWithValue("@LoggedDate", myDate);
    DatabaseManager.instance.ExecuteNonQuery(cmd);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...