Как обнаружить утечки соединения SqlServer в приложениях ASP.net?
Вопрос
В настоящее время я тестирую GUI в приложении ASP.net 2.0. СУБД - это SQL Server 2005. Хост - это Win Server 2003 / IIS 6.0.
У меня нет исходного кода приложения, потому что оно было запрограммировано внешней компанией, которая не выпускает код.
Я заметил, что приложение хорошо работает, когда я перезапускаю IIS, но после некоторого тестирования, после того, как я открыл и закрыл свой браузер в течение нескольких часов, приложение начинает работать все медленнее и медленнее. Мне было интересно, было ли это поведение из-за плохой практики закрытия соединений со стороны программистов: я подозреваю, что утечка открытого соединения в базе данных здесь.
Я полагаю, что .Net сборщик мусора в конечном итоге закроет их, но ... это может занять некоторое время, нет?
У меня есть SQL Server Management Studio, и я замечаю на мониторе активности, что в базе данных открыто довольно много соединений.
Из всего сказанного выше, несколько вопросов, связанных с основным вопросом:
<Ол>Есть ли способ узнать в SQL Server 2005, если соединения открыть, потому что они ждут, чтобы быть используется в пуле соединений или если они открыты, потому что они используются приложение?
Знает ли кто-нибудь о добре онлайн / бумажные ресурсы, где я мог научиться использовать производительность счетчики или другие инструменты чтобы помочь отследить такого рода вопросы?
Если счетчики производительности являются лучшими Решение, какие переменные, которые я надо смотреть?
Решение
Вы всегда можете проверить строки подключения из web.config (в основном, если у них активирован пул подключений, если у них включены какие-либо ограничения подключения).
Кроме того, если вы используете IIS 6, вы можете настроить свое веб-приложение на использование отдельного пула приложений и установить другой параметр для повторного использования памяти и процессов.
Что касается счетчиков производительности, вы можете проверить, как долго работает сборщик мусора, сколько памяти использует приложение и т. д.
Если у вас есть доступ к серверу sql, вы можете отслеживать соединения, сделанные из вашего приложения (для каждого установленного экземпляра SQL Server определены счетчики производительности).
В журнале MSDN было несколько статей. Также вы можете использовать библиотеку отладки SOS, чтобы присоединиться к процессу приложения и проверить его вручную.
И, если у вас нет исходного кода, попробуйте использовать Reflector получить исходные тексты приложения (они были бы очень полезны для отладки)
@Later edit: этот вопрос вы также можете найти здесь, на stackoverflow.com р>
Другие советы
Нашел эту тему, исследующую похожую проблему. Я предложил следующий 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 loginname = '<my_application_login>'
order by last_batch asc
Это дает вам все открытые соединения в конкретной базе данных и имени входа, вместе с последним sql, выполненным для этого соединения , отсортированным по времени, когда этот sql был выполнен.
Из-за пула соединений вы не можете просто полагаться на то, что вокруг висит много соединений, чтобы сказать вам, что у вас есть утечка соединений, потому что пул соединений будет поддерживать соединения, даже если они закрыты правильно из кода. Однако, если у вас есть утечка соединения, вы увидите, что некоторые соединения "замерзли" & # 8212; & # 8212; они будут отображаться в приведенном выше запросе, а & # 8220; last_batch & # 8221; метка времени никогда не изменится. Другие соединения также будут зависать, но каждый раз, когда на них запускается новый sql, & # 8220; last_batch & # 8221; отметка времени обновляется. Таким образом, эффект заключается в том, что замороженные соединения будут всплывать в верхней части этого запроса. Р>
Если у вас есть исходный код рассматриваемого приложения, тот факт, что он дает вам последний sql, выполненный для потерянного соединения, очень полезен для отладки. Р>
Я столкнулся с этой проблемой и обнаружил, что SQL Server Profiler является отличным инструментом. Я за короткое время проверил сайт и обнаружил множество создаваемых соединений (sp_who), которые не были повторно использованы Connection Pool, поэтому я просто открыл SQL Профилировщик сервера, а затем проверьте, все ли вызовы SP, сделанные из кода, сопровождались " sp_reset_connection " вызов. Если до начала новой партии вызова нет, вам просто не хватает первого соединения.
Справочник MSDN о ( счетчиках производительности ADO.NET ) довольно ясно о том, что вы можете искать при профилировании приложения. Вы можете контролировать счетчики, используя приложение perfmon , встроенное в Windows.
Кроме этого, я бы посоветовал узнать о пуле соединений ADO.NET. Если вы действительно подозреваете ошибку в их коде, вы можете посмотреть на нее, используя Reflector от Red Gate (пока бесплатно), который разбирает MSIL на C #.
Я бы начал с просмотра соединений и просмотра времени активности, а также выяснил, сможете ли вы найти элементы, которые поддерживают соединения открытыми. Р>
Я бы сказал, подумал, что если решение состоит в том, чтобы перезапустить IIS, вы могли бы также посмотреть на использование памяти приложением, чтобы увидеть, есть ли утечка памяти или что-то там, что действительно приводит к росту его площади.
Если бы открытые соединения были проблемой, в мониторе активности вы увидите ОЧЕНЬ большое количество соединений без активности.
Что касается счетчиков производительности, вы можете посмотреть на " SQL Server: General Stats " объект производительности.
Тодд Денлингер написал фантастический класс http://www.codeproject.com/KB/ database / connectionmonitor.aspx , который просматривает соединения с Sql Server и сообщает о тех, которые не были должным образом удалены в течение определенного периода времени. Подключите его к своему сайту, и он сообщит вам, когда возникнет утечка. Р>