Hogyan ne fussanak kétszer a scriptek?
Ne fusd le kétszer ugyanazt: okos előellenőrzés a DevOpsban
Mindenki ismeri azt a helyzetet, amikor egy telepítő szkript hibátlanul lefut, de aztán valami miatt mégis újra elindul. Lehet, hogy a CI/CD pipeline újrapróbálkozott, vagy valaki idegesen újra futtatta. A második futás nem kellene megtörténjen, mégis megtörténik – és ezzel adatbázis-migrációk futnak le kétszer, erőforrások duplikálódnak, vagy fizetési hookok többször is elindulnak.
Ilyenkor jön jól az előzetes állapot-ellenőrzés.
Az idempotencia-probléma
A fejlesztők gyakran feltételezik, hogy a szkriptjeik idempotensek. Vagyis ha többször is lefuttatjuk őket, ugyanazt az eredményt kapjuk, mint egyszer. Ez elméletben jó, de a gyakorlatban veszélyes.
Gondolj ezekre a példákra:
- AWS erőforrásokat létrehozó telepítő szkript
- Adatbázis-sémát módosító migráció
- Webhook, ami regisztrációkat kezel
- Adatszinkronizáló batch job
Mindegyikük problémás lehet, ha kétszer fut le rövid időn belül. Egy időbélyeg kétszer frissül, egy számláló feleslegesen nő, vagy egy ügyfél kétszer kap értesítést.
A gond az, hogy nem bizonyítod, hogy a szkript még nem futott le – csak bízol benne.
Előzetes állapot-ellenőrzés
Ahelyett, hogy az idempotenciára hagyatkoznál, érdemes inkább explicit végrehajtás-nyilvántartást használni. Mielőtt a szkript elkezdődne, kérdezd meg: „Ez már lefutott ebben a kontextusban?”
Ez az, amit a modern előellenőrző rendszerek csinálnak. Valamilyen állapotot tartanak nyilván – legyen az időbélyeg, hash, adatbázis-flag vagy elosztott lock – és ezzel megválaszolják a kérdést: „Valóban le kell most futtatni?”
Hogyan működik
- Állapot-lekérdezés – A szkript indulása előtt ellenőrzöd, hogy már volt-e ilyen végrehajtás
- Kontextus-ellenőrzés – Megerősíted, hogy nem ugyanazt a műveletet futtatod újra ugyanazokkal a paraméterekkel
- Lock vagy jelölés – Megjelölöd az aktuális futást „folyamatban” állapotként, hogy elkerüld a versenyhelyzeteket
- Végrehajtás – Lefuttatod a tényleges üzleti logikát
- Jelölés befejezésre – Frissíted az állapotot, hogy a futás lezártként legyen nyilvántartva
Ez a folyamat átalakítja a szkriptet „remélem, hogy idempotens” állapotból „bizonyítottam, hogy még nem futott le” állapotba.
Miért fontos ez a hostingban és infrastruktúrában
A domainek, DNS-változások és SSL-tanúsítványok esetében különösen fontos, hogy egyszer fussanak le csak. Pre-execution validation nélkül a DNS-változások duplán propagálhatnak, az SSL-tanúsítványok duplán generálhatوا