HWSW

Szökőmásodperc okozott kimaradást a Cloudflare-nél

Nem kezelte jól a szoftver, hogy az idő visszafelé is mehet. Az eredmény: részleges leállás a DNS-alrendszerben.

Nem tudta kezelni az év végi szökőmásodpercet a Cloudflare DNS-alrendszere, emiatt részleges kiesést szenvedett el a szolgáltatás. A DDoS-támadások ellen (is) védő Cloudflare most közzétette a hibáról szóló posztmortemet, fontos olvasmány lehet minden fejlesztőnek és üzemeltetőnek.

A kiesés azokat az ügyfeleket érintette, akik a Cloudflare-nél tartják a CNAME DNS rekordjaikat, és őket sem egységesen. A csúcson a DNS-lekérések mintegy 0,2 százalékát érintette a kiesés, és a Cloudflare-hez beérkező HTTP-lekérések 1 százaléka ütközött hibába.

Az idő mehet visszafelé

A szökőmásodpercek viszonylag rendszeres jelenségnek számítanak, ezekre azért van szükség, hogy a Föld saját forgását és az atomóráinkat szinkronban tudjuk tartani. Mivel a Föld mozgása fokozatosan lassul, félév vagy év végén szükség van egy-egy extra másodperc beiktatására. Ennek azonban meglepő hatása lehet azokra a szoftverekre, ahogy az alábbi eset is illusztrálja.

"A probléma gyökerét az a hit jelentette, hogy az idő nem mehet visszafelé. Esetünkben a kód egy része feltételezte, hogy két időpont különbsége minden esetben legalább nulla." - írja a poszt. A góban írt részlet a Go time.now() függvényét használja, ez azonban (a programozó várakozásával ellentétben) nem egy monoton növekvő függvény, ha a rendszeridőt valamiért visszafelé kell állítani (mint esetünkben), akkor két egymást követő lekérdezés különbsége negatív lehet. Ez egyébként a Go egyik problémája [1]is, nincs ugyanis a nyelvben egy egységesen hívható monoton időfüggvény, amellyel két időpont között megbízhatóan mérhető az eltelt idő, erre a célra platformfüggő alacsony szintű kódot kell bevetni.

xVisszatérve a problémára: a Cloudflare a DNS-feloldás teljesítményét a fenti kóddal méri. Mivel viszonylag gyors gépekről van szó, néhány ezredmásodperces válaszértékekről van szó, így ha egy másodperccel visszaállítjuk az órát, akkor ez az érték könnyen csúszhat negatívba. Mivel az algoritmus ezeket a válaszidőket átlagolja, néhány mérésnek le kell zajlania, míg az átlag negatívvá válik, ezt pedig a rand.Int63n() függvényének adja be - ez viszont nem kezel negatív argumentumot.

A javítás viszonylag egyszerű, nyilván ellenőrizni kell, hogy az idő éppen visszafelé jár-e, és amennyiben igen, azokat az értékeket el kell vetni (hiszen úgysem megbízhatóak). Majd ha lejár az óra visszatekerés hatása, újra lehet az értékeket használni a megadott célra. További izgalmas részletek a Cloudflare blogján [2].

Volt egyébként már hasonlóra probléma, emlékezetes módon 2012-ben a Microsoft Azure felhős szolgáltatása vált elérhetetlenné [3] a szökőév miatt. Akkor a biztonsági tanúsítványok kezelése nem bírt el ezzel az (általában) négyévente esedékes naptári jelenséggel.

A cikkben hivatkozott linkek:
[1] https://github.com/golang/go/issues/12914
[2] https://blog.cloudflare.com/how-and-why-the-leap-second-affected-cloudflare-dns/
[3] https://www.hwsw.hu/hirek/48180/microsoft-azure-leallas-cloud-felho.html
A cikk adatai:
//www.hwsw.hu/hirek/56620/cloudflare-szokomasodperc-go-nyelv-szoftver-ido-fuggveny.html
Író: Gálffy Csaba (galffy.csaba@hwsw.hu)
Dátum: 2017. január 02. 17:43
Rovat: vállalati it