Короткий ответ
Возможные пути — вынести состояние из инстанса во внешнее хранилище (сессии в управляемый кэш/БД, файлы в общее хранилище), что позволяет масштабировать горизонтально как обычный stateless-сервис; либо, если переписать приложение в разумные сроки нельзя, использовать вертикальное масштабирование и/или sticky-сессии как временное паллиативное решение с явно осознанными ограничениями.
Как это работает подробнее
вынос состояния во внешний управляемый сервис устраняет привязку запроса к конкретному инстансу, после чего балансировщик может направлять запросы на любой здоровый инстанс, а группа авто-масштабирования — свободно добавлять/убирать инстансы; sticky-сессии закрепляют клиента за конкретным инстансом по cookie, что позволяет масштабироваться для новых клиентов, но не решает равномерность распределения нагрузки и усложняет graceful-замену инстансов.
Пример кода
Текущее состояние: сессии в памяти процесса, временные файлы в /tmp инстанса
Вариант А (рефакторинг): сессии -> управляемый кэш (Redis-совместимый сервис),
временные файлы -> объектное/общее файловое хранилище
Результат: любой инстанс может обработать любой запрос, ASG масштабируется свободно
Вариант Б (паллиатив): sticky sessions по cookie на балансировщике,
вертикальное увеличение размера инстанса при росте нагрузки
Результат: ограниченное горизонтальное масштабирование, узкие места остаютсяЧто использовать на практике
- Рекомендация. для относительно небольшого объёма изменений вынос состояния в управляемый кэш — быстрая и надёжная победа; для приложений с глубокой зависимостью от локального диска потребуется более существенный рефакторинг или переход на общее файловое хранилище с учётом возросшей задержки сетевого доступа к файлам.
- Проверка. после варианта А тест с принудительным завершением случайного инстанса под нагрузкой не должен приводить к потере пользовательских сессий; в варианте Б тот же тест прервёт сессии пользователей, закреплённых за этим инстансом, что должно быть явно задокументировано как принятый риск.
- Компромисс. полный вынос состояния — самое устойчивое решение, обеспечивающее настоящее горизонтальное масштабирование, но требует времени и бюджета на рефакторинг и тестирование; sticky-сессии и вертикальное масштабирование дают быстрый результат с минимальными изменениями кода, но оставляют структурные ограничения — решение, что делать в первую очередь, должно явно взвешивать срочность, бюджет на рефакторинг и то, насколько критичен рост нагрузки именно сейчас.
Подводные камни
- Риск. внедрять sticky-сессии и считать задачу авто-масштабирования решённой, хотя нагрузка распределяется неравномерно и инстансы с «залипшими» сессиями невозможно безопасно вывести из ротации
- Риск. переносить файлы в общее хранилище без учёта возросшей задержки доступа
- Риск. пытаться масштабировать приложение вертикально на лету как замену горизонтальному масштабированию.