Назад |
Перейти на главную страницу
Обработка пиков трафика для приложения электронной коммерции среднего размера
Позвольте мне сначала кратко описать наш стек.
- Один экземпляр EC2 с 4 виртуальными ЦП и 16 ГБ ОЗУ под управлением Ubuntu [m4.xlarge]
- Один экземпляр RDS с 2 виртуальными ЦП и 8 ГБ ОЗУ под управлением MySQL 8 [db.m5.large]
- Мы используем Cloudfront для кеширования статических активов
- Мы используем Nginx в качестве веб-сервера
- Он поддерживается экземплярами tomcat, в которых работают наши веб-приложения Java.
- У нас есть 3 основных приложения, каждое из которых запускается в собственном экземпляре tomcat (веб-сайт Storefront, серверная часть администратора, платформа продавца)
Витрина магазина и платформа продавца общаются с административным сервером, используя REST API для важных событий, остальное у них есть прямая интеграция с RDS для БД.
Все наши приложения созданы на Java с использованием Spring и Hibernate в качестве фреймворков.
- Мы используем пул соединений с базой данных tomcat во всех приложениях
- Мы используем кеш памяти для полного каталога и других вещей, которые не часто меняются, чтобы избежать попадания в БД.
Что произошло:
В обычные дни у нас на сайте около 125 пользователей, по данным аналитики Google, и мы получаем примерно 1 заказ за каждые 2 месяца. Но однажды, когда мы проводили несколько агрессивных кампаний, у нас было около 4000 пользователей одновременно, и каждую минуту на сайте размещалось около 18 заказов. Поскольку мы обещаем доставку в тот же день, наша серверная часть и платформа продавца одинаково работали на полную мощность для обслуживания этих заказов.
Эта высокая нагрузка была на нашу систему в течение 4 часов, что привело к 20 простоям, что в совокупности составило около 50 минут простоя. В первую очередь это произошло из-за проблем с базой данных.
Наблюдаемая проблема
- Больше всего пострадало наше Backend-приложение. Примерно каждые 15 минут он начал выдавать ошибку, что не может получить соединение с базой данных. Иногда это разрешается автоматически через минуту или две, иначе нам нужно перезагрузить приложение Backend.
- Хотя Storefront не связан с Backend для всех операций. Но все же в то время как бэкэнд выдает ошибку. Приложение Storefront также перестало отвечать из-за истечения времени ожидания.
- Мы назначили каждому приложению около 200 подключений, но RDS по-прежнему использовала максимум 250 подключений, включая все приложения.
- ЦП RDS в то время работал в диапазоне более 80%
- Худший удар произошло, когда RDS перешел на 100% загрузку ЦП и остался там. Все перестает отвечать. Нам нужно закрыть все приложения, перезагрузить RDS и запустить снова, и после этого все было нормально до конца дня, даже при приличной нагрузке. Это стоило нам 15 минут простоя
Вопрос
Как я уже упоминал, мы работаем в среднем масштабе, поэтому у нас нет достаточного количества журналов, чтобы понять, почему и что на самом деле произошло в тот день. Что можно сделать, чтобы избежать подобных инцидентов в будущем? Как мы можем подготовиться, будь то изменение архитектуры приложения, масштабирование оборудования или что-то еще. Все предложения приветствуются
Я прикрепляю несколько метрик RDS Cloudwatch в тот день
Реляционные базы данных всегда связаны с проблемами масштабирования. Тем не менее вы можете попробовать следующее:
- Увеличьте размер экземпляра для RDS
- Используйте реплики чтения в RDS для своей базы данных и направьте все операции чтения из приложения на чтение реплики.
- Также я надеюсь, что вы наблюдали за использованием IOP и не достигли пределов. Было бы полезно подготовить IOP, если вы достигли пределов.
- Похоже, у вас также были проблемы с масштабированием на уровне приложения (витрина). Вы можете реализовать горизонтальное масштабирование, поместив свой сервер за балансировщик нагрузки и разрешив ему автоматическое масштабирование. Вы также можете увеличить количество экземпляров с помощью группы автомасштабирования перед запуском кампаний и уменьшить их после кампании (сделайте расчетное суждение).
- Также вы можете использовать схему выключателя (https://martinfowler.com/bliki/CircuitBreaker.html) между витриной и административной службой.