У нас есть производственная система, которая представляет собой приложение ASP.NET Web API
(классическое, а не .NET Core
), опубликованное в Azure
. Хранение данных Azure SQL Database
, и мы используем Entity Framework
для доступа к данным. API имеет среднюю нагрузку, 10-60 запросов в секунду и задержка upper_90
составляет 100-200 мс, что является целевой задержкой в нашем случае. Некоторое время назад мы заметили, что примерно каждые 20-30 минут наши сервисы останавливаются, а время ожидания увеличивается примерно до 5-10 секунд. Все запросы начинают работать медленно в течение минуты, а затем система восстанавливается сама. В то же время запросы не отбрасываются, все они просто выполняются дольше. в течение короткого периода времени (обычно 1 минута).
На нашей телеметрии HTTP-запросов (Azure) мы начинаем видеть следующую картинку:
Мы также можем видеть корреляцию с нашими показателями базы данных SQL Azure, такими как DTU (отбрасывание) и соединения (увеличение):
Мы проанализировали сервер и не увидели никакой корреляции с хостом (у нас только один хост) использование ЦП / памяти, оно стабильно при уровне использования ЦП 20-30% и использовании памяти 50%.
У нас также есть альтернативный источник телеметрии, который показывает то же самое поведение. Наша телеметрия измеряет задержку API и метрики базы данных, такие как количество активных соединений и количество пулов соединений (ADO.NET Connection Pool):
Что интересно,что каждый системный срыв сопровождается повышением количества соединенных соединений. И наши тесты показывают, что чем больше подключений в пуле, тем дольше вы ожидаете нового соединения из этого пула для выполнения следующей операции с базой данных. Мы проанализировали несколько предложений, но не смогли доказать или опровергнуть ни одно из них:
- утечка соединения ADO.NET (весь наш доступ к базе данных происходит в операторе using с правильным удалением соединения / возвратом в пул)
- Исчерпание сокета / порта - когда невозможно правильно отслеживать телеметрию по этому метрике
- Узкое место ЦП / памяти - диаграммы показывают, что узкого места
- DTU (единиц базы данных) нет - диаграммы показываютнет ни одного
На данный момент мы пытаемся выявить возможного виновника этого поведения. К сожалению, мы не можем определить изменения, которые привели к этому из-за отсутствия телеметрии, поэтому сейчас единственный способ решить проблему - это правильно ее диагностировать. И, конечно же, мы можем воспроизводить его только в производственном режиме под постоянной нагрузкой (даже если нагрузка невысокая, например, 10 запросов в секунду).
Каковы возможные причины такого поведения и как правильнодиагностировать и устранять неполадки?