Konrad Kowalski (rootsher)Principal Platform & Reliability Architect011111010110101100111011111010100010011000010110

Cofanie wydania: kod to najłatwiejsza część

data
kategoria
Reliability Engineering
także w
CI/CD · Databases
czytanie
2 min / 421 słów

Rollback wydania brzmi prosto.

text
wróć do poprzedniej wersji

W przypadku samego kodu często naprawdę jest prosto.

Można wskazać poprzedni obraz kontenera.

Można cofnąć release w platformie.

Można przełączyć ruch z green na blue.

Można wyłączyć flagę.

Problem zaczyna się wtedy, gdy nowe wydanie zdążyło zmienić świat poza własnym procesem.

Kod jest odwracalny

Artefakt aplikacji jest zwykle niemutowalny.

text
api:1.41.0
api:1.42.0

Jeżeli 1.42.0 ma błąd, można uruchomić 1.41.0.

To jest czysty przypadek rollbacku.

Warunek jest jeden:

text
stara wersja musi nadal umieć działać w aktualnym środowisku

To środowisko obejmuje konfigurację, schemat bazy, formaty wiadomości, zewnętrzne API i dane, które użytkownicy zdążyli zapisać.

Jeżeli nowa wersja zmieniła tylko logikę liczenia rabatu, rollback kodu może wystarczyć.

Jeżeli nowa wersja zmieniła strukturę danych, rollback kodu może uruchomić stary proces na nowym świecie.

I wtedy zaczyna się prawdziwy problem.

Migracje nie cofają się same

Najniebezpieczniejsze rollbacki dotyczą migracji.

Przykład:

sql
ALTER TABLE orders DROP COLUMN legacy_status;

Nowa wersja aplikacji już nie używa legacy_status.

Stara wersja nadal używa.

Jeżeli po takiej migracji cofniemy tylko kod, stara aplikacja może przestać działać natychmiast.

Dlatego bezpieczne zmiany schematu zwykle robi się w kilku krokach.

text
dodaj nowe pole
pisz do starego i nowego pola
przełącz odczyt na nowe pole
przestań pisać do starego pola
usuń stare pole dopiero po czasie

To jest nudniejsze niż jedna migracja.

Ale pozwala cofnąć kod w środku procesu.

Rollback nie jest wtedy "cofnij migrację".

Rollback brzmi:

text
wróć do poprzedniej wersji aplikacji, bo schemat nadal ją wspiera

Dane są jednokierunkowe częściej niż kod

Czasem migracja nie usuwa kolumny.

Czasem zmienia znaczenie danych.

Przykład:

text
status = paid

zamienia się na:

text
payment_state = captured
fulfillment_state = ready

Można napisać migrację w przód.

Nie zawsze da się napisać migrację w tył bez utraty informacji.

Jeszcze gorzej, jeśli po deployu użytkownicy zaczęli tworzyć nowe rekordy już w nowym modelu.

Stara wersja aplikacji może nie wiedzieć, co z nimi zrobić.

Dlatego pytanie przed wydaniem nie brzmi tylko:

text
czy mamy rollback?

Lepsze pytanie brzmi:

text
czy poprzednia wersja rozumie stan, który może powstać po deployu?

Skutki uboczne wychodzą poza bazę

Wydanie może też wysłać eventy, maile, webhooki albo zadania do kolejki.

Rollback kodu nie cofnie:

text
wysłanej wiadomości
opublikowanego eventu
wykonanej płatności
zadania, które czeka w kolejce
cache z nowym formatem
indeksu wyszukiwarki

Jeżeli nowa wersja opublikowała event w nowym formacie, stara wersja konsumenta może go nie zrozumieć.

Jeżeli nowa wersja zapisała cache w nowym kształcie, stara wersja może czytać błędne dane.

Jeżeli nowa wersja wysłała webhook do partnera, nie da się udawać, że to się nie stało.

Rollback ogranicza przyszłe szkody.

Nie kasuje automatycznie skutków, które już zaszły.

Feature flag to czasem lepszy rollback

Jeżeli problem dotyczy jednej ścieżki, najlepszym rollbackiem może być wyłączenie flagi.

text
nowy kod zostaje
nowe zachowanie znika

To jest szybsze niż przebudowanie obrazu albo kolejny rollout.

Ale działa tylko wtedy, gdy flaga została zaprojektowana jako prawdziwy przełącznik bezpieczeństwa.

Flaga, która ukrywa przycisk w UI, nie zatrzyma zadania cron.

Flaga, która wyłącza endpoint, nie cofnie migracji.

Flaga, która działa tylko przy odczycie, nie ochroni zapisu.

Minimalny runbook rollbacku

Dobry runbook cofania wydania powinien mieć kilka punktów.

text
jaki objaw uznajemy za powód rollbacku
kto podejmuje decyzję
który artefakt jest poprzednią dobrą wersją
czy migracje są kompatybilne w tył
czy trzeba wyłączyć flagi
czy trzeba zatrzymać kolejki albo joby
jak sprawdzamy, że rollback pomógł

Najważniejszy punkt jest prosty:

text
rollback kodu nie jest rollbackiem systemu

Jest tylko jednym z narzędzi.

Jeżeli błąd zdążył uszkodzić dane, trzeba przejść do recovery danych.