Период ожидания, прошедший до получения соединения из пула

#asp.net #sql #performance #timeout

#asp.net #sql #Производительность #время ожидания

Вопрос:

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

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

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

Спасибо!

Комментарии:

1. Какие версии ASP. Net и SQLServer?

2. когда я впервые прочитал строку темы, я подумал, что вы спасатель.

Ответ №1:

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

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

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

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

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

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

Вы можете увеличить настройку max threads с помощью этого 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 перестает отвечать на запросы, как только у него заканчиваются потоки.

Ответ №2:

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

Комментарии:

1. Или неявно утилизировать, поместив соединение в using() { ... } конструкцию.

2. В моем случае я не закрывал соединение.

Ответ №3:

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

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

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

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

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

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

Ответ №4:

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

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

Это было связано с тем, что я использовал 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);
}
  

Комментарии:

1. Почему это должно иметь какое-либо значение?

Ответ №5:

У меня возникла эта проблема с 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'"
  

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