Уменьшение простоя (downtime) при обновлении сетевого приложения
LVEE 2015
В связи с релизом nginx 1.9.0, в котором была добавлена возможность балансировки любых приложений работающих через TCP, материал данной статьи справедлив не только к веб ресурсам, но и к любым другим работающим поверх TCP (СУБД, системам аутентификации, каталогам LDAP, VoIP-системам и т.п.).
При обновлениях, да и некоторых других работах, простой (downtime) для сетевого приложения является неизбежным злом. Но с ним нужно и можно бороться.
Для примера рассмотрим простейший случай, как на рисунке ниже:
Имеется некое клиент-серверное приложение. Периодически возникает задача его обновлять. При обновлениях возникает время простоя, пользователи очень обижаются и перестаю пользоваться данным приложением (заходить на сайт, оставлять заявки с службу технической поддержки).
Первым этапом в улучшении приложения стала модификация сетевой инфраструктуры – добавился сервер для тестирования обновлений, так называемый staging-сервер:
Стало лучше, возможность успешной установки обновлений предварительно проверялась, проверялась и работоспособность основных функций приложения после обновления. Время простоя уменьшилось (как и недовольство пользователей), но не исчезло.
Следующим этапом в улучшении стало добавление обратного прокси в структуру приложения:
Данная структура обеспечила возможность горизонтального масштабирования системы и позволила гибко между серверами при необходимости (ликвидировать простои на время обслуживания).
Изначально было решено поступить следующим образом: при подготовке сервера к обновлению происходит синхронизация данных на staging сервер, затем на нем происходит обновление приложения и основная проверка работоспособности
Затем происходит переключение обратного прокси на staging сервер, переключение длится несколько секунд (из серьезных недостатков – мы теряем все активные сессии пользователей). В остальном – для конечного пользователя вообще ничего не меняется.
После переключения нагрузки на staging сервер, на production сервере обновляется приложение. После успешного обновления и проверки его жизнеспособности начинается синхронизация данных со staging (теоретически конечные пользователи уже внесли изменения в данных приложения).
После окончания синхронизации происходит переключение обратного прокси-сервера обратно на production сервер.
Но при тестировании на реальных данных нашелся небольшой процент пользователей который изменял данные в момент после синхронизации данных и до переключения между серверами.
В связи с этим, было решено изменить механизм работы приложения.
Был разработан механизм который переводил приложение в режим “только чтение” и уведомлял об этом пользователей. Перед началом обновления production сервер переводился в режим “только чтение”.
После этого происходила синхронизация на staging сервер. Приложение на staging сервере также находится в режиме только чтение.
После этих манипуляций происходит переключение production прокси на staging, при этом мы убрали вероятность потери данных в момент синхронизации-переключения. Пользователи получили доступ к приложению и его данным только на чтение на момент обновления, количество негативных отзывов стало минимальным за все время (все отнеслись с пониманием о висящей плашке предупреждающих о технических работах). Далее – переключение приложения на staging, обновление production сервера, переключение обратно и лишь затем – отключение режима “только на чтение”.
Вместо заключения
Мы добились высокой доступности приложения. При этом, синхронизация данных максимально упрощена, необходимости в изменение работы логики приложения нет (что в свою очередь позволяет ее применять к уже существующим решениям без добавления / изменения логики работы).
Abstract licensed under Creative Commons Attribution-ShareAlike 3.0 license
Back