Blog

Riasztások, amelyek egyszer szólnak, nem szerverenként egyszer

Az egyik működési riasztásunk — „alacsony kredit” egy builder publikált appjához — egyszer érkezne meg naponta. Egy délután viszont ötször jött meg. Az ok: az API minden példánya a saját memóriájában jegyezte, mely riasztásokat küldte már el, így a két szerver kétszer küldte el, és minden deploy törölte ezt a memóriát, így újra elküldték. Ugyanez a minta egy háttérfeladatot is kétszer futtatott le. Mindkettő most egy közös tárolón keresztül koordinálja magát, és ha a tároló nem érhető el, mindkettő a biztonságos oldalra dől.

A tünet

A Mythex csapatriasztásokat küld, ha valaminek figyelemre van szüksége: egy szolgáltatás leállt, egy feladat elakadt, vagy egy builder kreditegyenlege fogy, miközben az appja publikálva van. Minden riasztásnak van deduplikációs ablaka — egy időszak, amely alatt ugyanaz a riasztás csak egyszer megy ki. Az alacsony kredit riasztásnál ez az ablak 24 óra.

Öt egyforma riasztás egy délutánon azt jelentette, hogy az ablak nem tartott. Ami rosszabb: párban jöttek, nagyjából 11 perces különbséggel.

Miért történt

Az alerts csomagunk a deduplikációt memóriában tartotta: egy táblázat, amely „riasztáskulcs → mikor küldtük utoljára” párokat tárol, a futó folyamaton belül. Ez akkor működik, ha egy folyamat van, amely sosem indul újra. A productionben egyik sem igaz:

  • Két API-replika. A productionben az API két példányban fut. Mindegyiknek külön táblázata volt, így mindegyik egyszer küldte el a riasztást. Ezek a párok.
  • Deployok. Minden deploy mindkét replikát új folyamatokkal és üres táblázatokkal cseréli le. Deploy után a riasztás újra kiment, mintha soha nem küldték volna el.

A két riasztás közötti ~11 perces különbség abból a feladatból származott, amely ezt a riasztást előállítja. Ez mindkét replikán fut, és zárat vesz, így a replikák felváltva nyerik el, és mindegyik akkor emelte a riasztást, amikor sora került.

A ugyanebben a kódban volt egy második, csendesebb hiba is. Hogy a táblázat ne nőjön a végtelenségig, 500 kulcsnál elkezdte önmagát metszeni: minden 15 percnél régebbi bejegyzést törölt, függetlenül az ablakától. Terhelés alatt egy 24 órás deduplikáció negyed óráig tartott.

A javítás

Egy közös rekord riasztásonként

Mielőtt az API riasztást küld, most a riasztás deduplikációs kulcsát Redisben foglalja le — ez egy közös memóriatároló, amelyhez mindkét replika csatlakozik, és amely nem indul újra, ha az API újraindul. A foglalás egyetlen művelet: „ezt a kulcsot csak akkor állítsd be, ha még nem létezik, és az ablak végén járjon le”. Amelyik replika előbb foglal, az elküldi a riasztást; a másik azt találja, hogy a kulcs foglalt, és csendben marad. Egy deploy utáni új folyamat is megtalálja még a kulcsot.

A kulcs és az ablak ugyanabból a szabályból származik, amelyet az alerts csomag használ, de most a kettő közösen használja, így a két réteg nem térhet el abban, mi számít „ugyanannak a riasztásnak”.

Hibánál nyitva maradjon, ne zárva

A legfontosabb döntés az volt, mi történjen, ha a Redis nem érhető el. Úgy döntöttünk, hogy a riasztás mindenképp kimegy. Ha a Redis nem működik, vagy 1,5 másodpercen belül nem válaszol, a riasztás elmegy. Egy duplikált riasztás zaj. Egy elveszett riasztás azt jelenti, hogy valakit nem értesítettek.

A legsúlyosabb riasztásokat, a P0-kat a deduplikáció egyáltalán nem tartja vissza.

Minden bejegyzés megtartja a saját ablakát

Az alerts csomag saját memóriabeli deduplikációjában most minden bejegyzés tárolja, mikor ér véget az ablaka, a metszés pedig csak azokat a bejegyzéseket távolítja el, amelyek ablaka lejárt. Egy 24 órás kulcs 24 óráig megmarad, függetlenül attól, hány másik riasztás érkezik.

Ugyanez a hiba máshol

Ugyanez a minta egy háttérfeladatot is megduplázott: egy egyeztető feladatot, amely a munkaterületek állapotának nyilvántartását a sandbox-szolgáltatónk adataihoz igazítja. Minden körben listázza a fiók összes sandboxát — a productionben több ezret, körülbelül öt másodperc alatt —, plusz minden futó vagy szünetelő projektet. Mindkét replika két percenként futtatta.

Az írásai idempotensek — egyszeri és kétszeri futtatásuk ugyanazt az eredményt adja —, így semmi nem tört el. Csak kétszer annyi munka volt. Most minden két perces ablakot Redisben foglalunk le ugyanúgy, ahogy a használati mérőink is foglalták a sajátjaikat, és csak az a replika futtatja a kört, amelyik a foglalást megszerezte. Ha a Redis nem érhető el, a kör mégis lefut: a munka kétszeri elvégzése ártalmatlan, a munka elmaradása nem az.

Hogyan teszteltük

A tesztek a valódi felállást modellezik. Az alerts modult kétszer töltik be, mint két külön „replikát”, mindkettőt egy közös tárolóra irányítják, mindkettőből kiemelnek ugyanazt a riasztást, majd betöltenek egy harmadik, friss példányt, hogy egy „deploy utáni” állapotot szimuláljanak, és újra kiemelik. Pontosan egy riasztás megy ki. További tesztek ellenőrzik, hogy egy másik builder riasztása is kimegy, hogy egy P0 mindkét replikából elmegy, és hogy a riasztás akkor is kimegy, ha a tároló leállt vagy az időkeretet túllépi. A metszés javításának saját tesztje van: egy 24 órás kulcs túléli, miközben 600 másik riasztás érkezik 20 perccel később.

Az egyeztető feladathoz két replika ugyanabban a pillanatban ketyeg, plusz egy harmadik ketyegés ugyanabban az ablakban, és ezek egyetlen listázást eredményeznek.

Amit ebből tanultunk

  • A memóriabeli állapot folyamatonként létezik. Minden, aminek szervereken át igaznak kell lennie — „egyszer küldve”, „egyszer futtatva” —, olyan helyen kell éljen, amelyet megosztanak.
  • A deployok újraindítások. Az az állapot, amely csak a következő újraindításig marad meg, egy átlagos munkanapon nem marad meg.
  • Döntsd el, melyik irányba hibázzon a rendszer. Riasztásoknál egy leálló közös tároló legyen több riasztás, ne kevesebb.
  • A mintát keresd, ne csak az előfordulást. A riasztás volt a hangos eset; a megduplázott egyeztető feladat ugyanez a hiba volt, csendben pazarolva a munkát.

Az egész nem látszik a Mythexen belülről. Arról, hogyan tartjuk stabilan a platformot, lásd hogyan értük el, hogy a deployok során nulla 502-es hiba legyen és a hiányzó swap-fájl cikkeinket. Ha új vagy abban, hogy egy szolgáltatásból több példány fut, az mi a szerver? útmutatónk az alapokat tárgyalja.

Mythex · Pricing · Építs bármit AI-val · Weboldal- és alkalmazássablonok · A Mythex összehasonlítva · AI-alapú alkalmazásépítési szószedet · Ingyenes eszközök AI-alapú alkalmazásépítéshez · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)