Друзья, хочу поделиться интересным случаем внезапной деградации производительности веб-приложения, и как мы это починили. Материал может быть полезен прежде всего программистам, чтобы помочь как можно быстрее решить имеющиеся проблемы с производительностью, а также избежать их в будущем.
О приложении
Информационный сайт, основной функционал - чтение электронных книг (pdf, epub), пользователи - учителя и школьники. Под капотом Java + Spring Boot, статика в виде CSS, JS, HTML, все внутри одного jar файла. Приложение запущено в Amazon за балансировщиком нагрузки на EC2-инстансах, в качестве базы данных MySQL в RDS, также использутся CDN для храниния книг, запросы контента книг проксируются через приложение, файлы в районе 50 Мегабайт. Нагрузка в пиках в районе 1000 пользователей в минуту.
Инцидент
За несколько лет разработки с приложением каких-то особых проблем не наблюдалось, поэтому фокус внимания был на разработке фич, пока внезапно не прилетел в поддержку тикет. У пользователей, вместо страницы авторизации, белый экран - серьезная проблема, требующая моментального устранения.
Расследование
Первое, что проверили, запущено ли все еще приложение, оно могло прекратить выполнение по причине ошибки, приложение было запущено, судя по логам ошибок и перезапусков не было. Установили с помощью curl, что приложение все же отдает статику, но очень медленно, от того пользователи и видели белый экран. Проблема воспроизводилась с различных локаций, а значит не связана с Интернет-провайдером пользователей.
Метрики показывали значительное увеличение запросов, что могло послужить причиной деградации производительности. Следовательно, следующей гипотезой стала нехватка ресурсов, вдруг приложению не хватает мощности процессора и от того оно отвечает медленно? Однако, потребление CPU было сильно меньше 100%, как на инстансах приложения, так и базы данных. Снова мимо.
В чем еще может быть причина медленной работы приложения? При нехватке оперативной памяти, если память уходит в своп, также могут появляться задержки, а еще, вероятно, из-за возросшего трафика не хватает ширины сетевого канала на стороне сервера. Однако, по результатам проверки, ничего из этого также не было причиной.
Получалось, по всему, приложение не особо нагружает инфраструктуру, но и работать так же отказывалось, такое может быть от задержек, кто-то кого-то явно ждал. Может, запросы к базе идут с задержкой по причине внутренних блокировок? Судя по логам SQL-запросов и это не было причиной.
Следующей гипотезой стала нехватка потоков для отработки запросов, вдруг запросы встают в очередь от того, что все потоки заняты? К сожалению, у нас не было настроено мониторинга внутреннего состояния приложения и пришлось работать наугад. Тут вспомнили про то, что приложение раздает довольно тяжелую статику из CDN, а если еще и у клиента Интернет не самый быстрый, то поток будет занят, пока все данные не передаст, бинго. Как проверить? Изменили метод, чтобы вместо проксирования контента возвращал редирект на CDN, и проблема с производительностью сразу ушла.
Выводы
1. Собирайте метрики. Полезно знать, сколько времени занимает выполнения каждого метода приложения, можно отследить во времени, если метод начинает работать медленнее, возможно, с этим что-то пора делать.
2. Регулярно проверяйте метрики и ускоряйте самые медленные среди самых частых вызовов. Тогда можно улучшать производительность заранее, не дожидаясь пока приложение упадет. Облегченные методы позволят сэкономить на железе.
3. Имейте возможность быстрого масштабирования приложения. Тут не только инфраструктурный, но и архитектурный вопрос. Если внезапно выросла нагрузка и скорость работы приложения упала, быстрее всего добавить мощности железа и потом в спокойном режиме оптимизировать код и тогда можно обратно уменьшить железо. Облачные провайдеры, такие как Amazon, позволяет это делать легко. В последнее время актуально становится иметь аналоги внутри РФ, тут стоит присмотреться к Yandex Cloud и VK Cloud, я лично с ними пока не работал, сказать ничего не могу.
Спасибо, что заглянули,
добавляйтесь в
Telegram
канал и будьте в курсе новинок.
Если Вам было интересно, можете поддержать автора