Блог

Аларми што се активираат еднаш, а не еднаш на секој сервер

Една од нашите оперативни аларми, „низок кредит“ за објавена апликација на градител, требаше да стигне до нас најмногу еднаш дневно. Едно поподне стигна пет пати. Причината: секоја копија на нашиот API ја памтеше во својата меморија кои аларми веќе ги испратила, па два сервери ги испраќаа двапати, а секое распоредување ја брише таа меморија и им дозволуваше повторно да испратат. Истиот образец имаше и background задача што ја работеше двапати. И двете сега се координираат преку заедничко складиште, а и двете грешат на безбедната страна ако тоа складиште не е достапно.

Симптомот

Mythex ги испраќа своите аларми на тимот кога нешто бара внимание: услуга е надвор од функција, задача е заглавена или кредитниот баланс на градител е мал додека неговата апликација е објавена. Секој аларм има прозорец за дедупликација, период во кој истиот аларм се испраќа само еднаш. За алармот за низок кредит, тој прозорец е 24 часа.

Пет копии од истиот аларм во едно поподне значеше дека прозорецот не држи. Уште полошо, доаѓаа во парови, со околу 11 минути разлика.

Зошто се случи

Пакетот за аларми ја чуваше дедупликацијата во меморија: табела „клуч на алармот → кога последен пат е испратен“, во работечкиот процес. Тоа функционира кога има еден процес што никогаш не се рестартира. Продукцијата нема ниту едно од тоа:

  • Две API реплики. Продукцијата работи со две копии на API. Секоја имаше своја табела, па секоја го испрати алармот еднаш. Тоа се паровите.
  • Распоредувања. Секое распоредување ги заменува двете реплики со нови процеси и празни табели. По распоредувањето, алармот повторно се испраќаше, како никогаш да не бил испратен.

Разликата од ~11 минути меѓу двата аларми во секој пар потекнуваше од задачата што го подига овој аларм. Таа работи на двете реплики и зема заклучување, па репликите ја добиваат по ред, и секоја го подигаше алармот кога ќе дојде нејзиниот ред.

Во истиот код имаше и втора, потивка грешка. За да не расте табелата бескрајно, таа се чистеше кога ќе достигне 500 клучеви: брише секој запис постар од 15 минути, без оглед на неговиот прозорец. Под оптоварување, 24-часовна дедупликација можеше да трае една четвртина од час.

Поправката

Една заедничка евиденција за секој аларм

Пред API да испрати аларм, сега го заклучува неговиот клуч за дедупликација во Redis, заедничко складиште во меморија до кое двете реплики пристапуваат и кое не се рестартира кога се рестартира API-то. Заклучувањето е една операција: „постави го овој клуч само ако не постои и истечи го по прозорецот“. Која реплика прва ќе го заклучи, ја испраќа алармот; другата го најде клучот зафатен и молчи. Нов процес по распоредување го наоѓа клучот уште таму.

Клучот и прозорецот доаѓаат од истото правило што го користи пакетот за аларми, сега споделено меѓу двата слоја, па не може да се расходат за тоа што значи „ист аларм“.

Грешка на отворено, не на затворено

Најважната одлука беше што да се направи кога Redis не е достапен. Избравме алармот сепак да се испрати. Ако Redis е надвор од функција или не одговори во рок од 1,5 секунда, алармот заминува. Дупликат аларм е бучава. Изгубен аларм значи дека некој не е известен.

Најсериозните аларми, P0, воопшто не се задржуваат од дедупликација.

Секој запис го задржува својот прозорец

Во сопствената дедупликација во меморија на пакетот за аларми, секој запис сега го чува моментот кога неговиот прозорец завршува, а чистењето ги брише само записите чиј прозорец е завршен. Клуч од 24 часа останува 24 часа, без оглед колку други аларми пристигнуваат.

Истата грешка, на друго место

Истиот образец ја удвои и една background задача: процес на усогласување кој ја држи нашата евиденција за статусот на секој работен простор во склад со нашиот провајдер на sandbox-и. Секое поминување ги наведува сите sandbox-и во сметката (илјадници во продукција, околу пет секунди) плус секој работен или паузиран проект. Двете реплики го извршуваа на секои две минути.

Неговите запишувања се идемпотентни, односно извршувањето двапати дава ист резултат како еднаш, па ништо не се расипа. Само беше двојно повеќе работа. Сега секој прозорец од две минути се заклучува во Redis на ист начин како што нашите мерачи на користење веќе ги заклучуваат своите, и само репликата што ќе го заклучи го извршува поминувањето. Ако Redis не е достапен, поминувањето се извршува сепак: работата двапати не е штетна, а неизвршувањето е.

Како го тестиравме

Тестовите го моделираат вистинското поставување. Го вчитуваат модулот за аларми двапати, како две одвоени „реплики“, ги насочуваат и двете кон едно заедничко складиште, го подигаат истиот аларм од секоја, па вчитуваат трета нова копија за да стои за „по распоредување“ и повторно го подигаат. Испраќа се точно еден аларм. Други тестови проверуваат дека аларм за друг градител сè уште излегува, дека P0 се испраќа од двете реплики и дека алармот се испраќа и кога складиштето е надвор од функција или задоцни над рокот. Поправката на чистењето има свој тест: клуч од 24 часа преживува 600 други аларми што пристигнуваат 20 минути подоцна.

За задачата за усогласување, две реплики што тикаат во исто време, плус трет тик во истиот прозорец, произведуваат едно листање.

Што научивме

  • Состојбата во меморија е по процес. Сè што мора да биде точно низ сервери, како „испратено еднаш“ или „извршено еднаш“, мора да живее каде што тие ја споделуваат.
  • Распоредувањата се рестартирања. Состојба што преживува само до следното рестартирање не преживува обичен работен ден.
  • Одлучете на која страна да грешите. За аларми, складиште што е надвор од функција треба да значи повеќе аларми, а не помалку.
  • Барајте го образецот, не само примерот. Алармот беше гласниот случај; двојното усогласување беше истата грешка, тивко трошејќи работа.

Ништо од ова не е видливо однатре во Mythex. За повеќе за тоа како ја држиме платформата стабилна, видете како стигнавме до нула 502 грешки при распоредувања и недостасувачката swap датотека. Ако сте нови со идејата за работење на повеќе копии од една услуга, нашиот водич за што е сервер ги покрива основите.

Mythex · Pricing · Градете што било со AI · Шаблони за веб-страници и апликации · Mythex во споредба · Речник за градење апликации со AI · Бесплатни алатки за градење апликации со AI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն 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 简体中文 繁體中文(香港) 繁體中文(台灣)