Эластичность и управляемые сервисы — Примеры

Пример 1 — Вынос состояния из экземпляра

Сервис пишет каждую загрузку на собственный локальный диск и записывает в базу путь к ней. За балансировщиком скачивание работает, только когда запрос попадает на экземпляр, принявший файл. Решите, где должен жить файл, и перепишите оба шага.

POST /uploads   -> записать /var/data/uploads/91a2.pdf, сохранить этот путь
GET  /uploads   -> прочитать путь из базы, открыть файл локально

Решение

POST /uploads   -> положить объект в управляемое объектное хранилище, сохранить
                   ключ 91a2.pdf в базе
GET  /uploads   -> прочитать ключ, забрать объект из хранилища

Состояние, которое должно пережить экземпляр, теперь живёт в сервисе, спроектированном его переживать, и любой экземпляр может отдать любое скачивание. Хранить загрузки на локальном диске — обычная оплошность: файл существует ровно на одном экземпляре, поэтому второй экземпляр возвращает ошибку об отсутствующем файле, а развёртывание нельзя сократить.

Пример 2 — Доводим работу до конца, прежде чем экземпляр исчезнет

Рабочий процесс забирает задачи из очереди и держит одну в памяти, пока она выполняется. Он игнорирует сигнал завершения платформы, и плавная замена сообщает о неудачных задачах на каждом шаге. Перепишите путь завершения рабочего процесса.

def run():
    while True:
        job = queue.take()
        process(job)

Решение

stopping = False

def request_stop():
    global stopping
    stopping = True          # прекратить приём новой работы

def run():
    while not stopping:
        job = queue.take()
        process(job)
    queue.requeue_in_flight()  # вернуть незавершённую задачу

Поскольку цикл теперь перестаёт брать работу и возвращает задачу, которую держит, льготный период платформы может закончиться чисто, и ни одна задача не теряется при удалении экземпляра. Игнорировать сигнал — обычная ошибка: процесс убивают на середине задачи, и каждое плавное развёртывание теряет работу в обработке, что выглядит как проблема очереди, а не как проблема завершения.

Подставьте свои имена сервисов и детали хранилища вместо условных значений в этих набросках.