Как обнаружить утечки соединения SqlServer в приложениях ASP.net?

В настоящее время я тестирую GUI на приложении ASP.net 2.0. RDBMS - это SQL Server 2005. Хост - это Win Server 2003/IIS 6.0.

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

Я заметил, что приложение работает хорошо, когда я перезапускаю IIS, но после некоторого тестирования после того, как я открыл и закрыл свой браузер на пару часов, приложение начинает становиться все медленнее и медленнее. Мне было интересно, было ли это поведение вызвано плохой практикой закрытия контактов со стороны программистов: я подозреваю, что здесь есть открытая утечка связи.

Я думаю, сборщик мусора .Net в конечном итоге закроет их, но... это может занять некоторое время, нет?

У меня есть SQL Server Management Studio, и я заметил из монитора активности, что в базе данных открыто несколько подключений.

Из всего сказанного выше, вот некоторые вопросы, связанные с основным вопросом:

  • Есть ли способ узнать в SQL Сервер 2005, если соединения открыты, потому что они ждут, чтобы быть используется в пуле соединений или если они открыты, потому что они используются приложение?

  • Знает ли кто-нибудь о хорошем онлайн/бумажные ресурсы, где я мог бы узнать, как использовать производительность счетчики или другие инструменты для отслеживания такого рода вопросы?

  • Если счетчики производительности являются лучшими решение, каковы переменные, которые я следует смотреть?

Ответ 1

Вы всегда можете проверить строки подключения из web.config(в основном, если они активировали пул соединений, если они имеют какие-либо ограничения подключений).

Кроме того, если вы используете IIS 6, вы можете настроить для своего веб-приложения отдельный пул приложений и установить другой вариант для утилизации памяти и процессов.

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

Если у вас есть доступ к серверу sql, вы можете отслеживать подключения, созданные из вашего приложения (для каждого установленного экземпляра SQL Server определены счетчики производительности).

В MSDN Magazine были опубликованы статьи. Также вы можете использовать библиотеку отладки SOS для присоединения к приложению и проверить ее вручную.

И если у вас нет исходного кода, попробуйте использовать Reflector, чтобы получить источники приложения (они было бы очень полезно для отладки)

@Later edit: вы можете проверить этот question здесь также на stackoverflow.com

Ответ 2

Нашел эту тему, исследуя аналогичную проблему. Я придумал следующий sql как хороший способ отладки негерметичных соединений в SQL Server:

SELECT S.spid, login_time, last_batch, status, hostname, program_name, cmd,
(
      select text from sys.dm_exec_sql_text(S.sql_handle)
) as last_sql
FROM sys.sysprocesses S
where dbid > 0
and DB_NAME(dbid) = '<my_database_name>'
and loginame = '<my_application_login>'
order by last_batch asc

Это дает вам все открытые соединения в конкретной базе данных и логин, а также последний sql, выполненный в этом соединении, отсортированный по времени, когда этот sql был выполнен.

Из-за пула соединений, вы не можете просто полагаться на то, что существует множество подключений, которые сообщают вам, что у вас есть утечка соединения, потому что объединение пулов будет поддерживать соединения, даже если они правильно закрыты из кода. Однако, если у вас есть утечка соединения, то вы увидите, что некоторые соединения становятся "замороженными" - они будут отображаться в вышеуказанном запросе, а временная метка "last_batch" никогда не изменится. Другие соединения также будут перемещаться, но каждый раз, когда на них запускается новый sql, метка "last_batch" обновляется. Таким образом, эффект заключается в том, что замороженные соединения будут всплывать в верхней части этого запроса.

Если у вас есть исходный код рассматриваемого приложения, тот факт, что это дает вам последний sql, выполненный в сиротском соединении, очень ценен для отладки.

Ответ 3

Я столкнулся с этой проблемой и нашел, что SQL Server Profiler является отличным инструментом, я проверил сайт в ходе короткого тестирования и заметил множество создаваемых соединений (sp_who), которые не были повторно использованы пулом соединений, поэтому я просто открыл SQL Server Profiler, а затем проверить, были ли все вызовы SP, сделанные из кода, вызовом "sp_reset_connection". Если вызов не существует до начала новой партии, у вас просто отсутствует первое соединение.

Ответ 4

Ссылка MSDN о (счетчики производительности ADO.NET) довольно ясно о том, что вы можете искать при профилировании приложения. Вы можете контролировать счетчики, используя perfmon приложение, встроенное в Windows.

Кроме этого, я бы посоветовал узнать о пуле соединений ADO.NET. Если вы действительно подозреваете ошибку в своем коде, вы можете взглянуть на нее, используя Red Reflector (бесплатно на данный момент), который разбирает MSIL в С#.

Ответ 5

Я хотел бы начать с просмотра соединений и просмотра времени активности и посмотреть, сможете ли вы найти элементы, которые поддерживают открытые подключения.

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

Если открытые подключения были проблемой, в мониторе активности вы увидите ОЧЕНЬ большое количество подключений без активности.

Для счетчиков производительности вы можете начать просмотр объекта производительности SQL Server: общая статистика.

Ответ 6

Тодд Денлингер написал фантастический класс http://www.codeproject.com/KB/database/connectionmonitor.aspx, который следит за подключениями и отчетами Sql Server к тем, которые не были должным образом удалены в течение периода время. Подключите его к вашему сайту, и он сообщит вам, когда произойдет утечка.