Բլոգ

Ահազանգեր, որոնք գործում են մեկ անգամ, ոչ թե մեկ անգամ յուրաքանչյուր սերվերի համար

Մեր գործառնական ահազանգերից մեկը՝ «ցածր կրեդիտներ» կառուցողի հրապարակված հավելվածի համար, նախատեսված է հասնել մեզ առավելագույնը օրական մեկ անգամ։ Մի կեսօրվա ընթացքում այն հասավ հինգ անգամ։ Պատճառը. մեր API-ի յուրաքանչյուր պատճենը իր հիշողության մեջ էր պահում, թե որ ահազանգերն է արդեն ուղարկել, ուստի երկու սերվերը այն ուղարկեցին երկու անգամ, և յուրաքանչյուր deploy ջնջում էր այդ հիշողությունը և թույլ տալիս նորից ուղարկել։ Նույն օրինաչափությունը կրկնապատկում էր նաև ֆոնային աշխատանքը։ Երկուսն էլ այժմ համակարգվում են համօգտագործվող պահոցի միջոցով, և երկուսն էլ ձախողվում են անվտանգ կողմում, եթե այդ պահոցը հասանելի չէ։

Սիմպտոմը

Mythex-ը ուղարկում է իր թիմի ահազանգերը, երբ ինչ-որ բան պահանջում է ուշադրություն. ծառայությունը անջատված է, աշխատանքը կանգնել է, կամ կառուցողի կրեդիտների մնացորդը ցածր է, մինչդեռ նրա հավելվածը հրապարակված է։ Յուրաքանչյուր ահազանգ ունի dedupe պատուհան՝ ժամանակահատված, որի ընթացքում նույն ահազանգը ուղարկվում է միայն մեկ անգամ։ Ցածր կրեդիտների ահազանգի համար այդ պատուհանը 24 ժամ է։

Մեկ կեսօրվա ընթացքում նույն ահազանգի հինգ պատճենը նշանակում էր, որ պատուհանը չէր պահում։ Ավելի վատ՝ դրանք գալիս էին զույգերով, մոտավորապես 11 րոպե տարբերությամբ։

Ինչու դա տեղի ունեցավ

Մեր ահազանգերի փաթեթը dedupe-ը պահում էր հիշողության մեջ. աղյուսակ «ահազանգի բանալի → երբ վերջին անգամ ուղարկվել է», աշխատող գործընթացի ներսում։ Դա աշխատում է, երբ կա մեկ գործընթաց, որը երբեք չի վերագործարկվում։ Արտադրությունը ոչ մեկը չունի.

  • Երկու API replica. Արտադրության մեջ աշխատում են API-ի երկու պատճեն։ Յուրաքանչյուրն ուներ իր աղյուսակը, ուստի յուրաքանչյուրն ահազանգն ուղարկում էր մեկ անգամ։ Դրանք են զույգերը։
  • Deploy-ներ. Յուրաքանչյուր deploy երկու replica-ներն էլ փոխարինում է նոր գործընթացներով և դատարկ աղյուսակներով։ Deploy-ից հետո ահազանգը նորից գնաց, կարծես երբեք չէր ուղարկվել։

Երկու ահազանգերի միջև 11 րոպեանոց տարբերությունը յուրաքանչյուր զույգում գալիս էր այն աշխատանքից, որը բարձրացնում է այս ահազանգը։ Այն աշխատում է երկու replica-ների վրա և կողպում է, այնպես որ replica-ները հերթով են հաղթում, և յուրաքանչյուրը բարձրացնում էր ահազանգը, երբ իր հերթն էր գալիս։

Նույն կոդում կար երկրորդ, ավելի անաղմուկ սխալ. աղյուսակը անվերջ չաճելու համար, երբ այն հասնում էր 500 բանալիի, ինքն իրեն մաքրում էր՝ ջնջելով ամեն գրառում, որը 15 րոպեից ավելի հին էր, անկախ նրա պատուհանից։ Բեռի տակ 24-ժամյա dedupe-ը կարող էր տևել ընդամենը քառորդ ժամ։

Շտկումը

Մեկ համօգտագործվող գրառում յուրաքանչյուր ահազանգի համար

Ահազանգը ուղարկելուց առաջ API-ն այժմ իր dedupe բանալին ապահովում է Redis-ում. համօգտագործվող հիշողության պահոց, որին միանում են երկու replica-ները և որը չի վերագործարկվում, երբ վերագործարկվում է API-ն։ Այս պահպանումը մեկ գործողություն է. «սահմանիր այս բանալին միայն եթե այն գոյություն չունի, և ժամկետը լրացրու պատուհանից հետո»։ Ով առաջինն է պահպանում, ուղարկում է ահազանգը. մյուսը տեսնում է, որ բանալին զբաղված է, և լռում է։ Deploy-ից հետո նոր գործընթացը գտնում է, որ բանալին դեռ այնտեղ է։

Բանալին և պատուհանը գալիս են նույն կանոնից, որ օգտագործում է ահազանգերի փաթեթը, և որն այժմ համօգտագործվում է երկուսի միջև, ուստի երկու շերտերը չեն կարող տարբեր լինել այն հարցում, թե ինչ է համարվում «նույն ահազանգ»։

Բաց թողնել, ոչ թե փակել

Ամենակարևոր որոշումն այն էր, թե ինչ անել, երբ Redis-ին հասնել չի հաջողվում. մենք որոշեցինք ամեն դեպքում ուղարկել ահազանգը։ Եթե Redis-ը անջատված է, կամ չի պատասխանում 1,5 վայրկյանում, ահազանգը գնում է։ Կրկնօրինակ ահազանգը աղմուկ է. բաց թողնված ահազանգը նշանակում է, որ ինչ-որ մեկին չեն տեղեկացրել։

Ամենածանր ահազանգերը՝ P0-ը, dedupe-ով երբեք չեն պահվում։

Յուրաքանչյուր գրառում պահում է իր պատուհանը

Ահազանգերի փաթեթի սեփական հիշողության dedupe-ում յուրաքանչյուր գրառում այժմ պահում է, թե երբ է ավարտվում իր պատուհանը, և մաքրումը հեռացնում է միայն այն գրառումները, որոնց պատուհանն ավարտվել է։ 24-ժամյա բանալին մնում է 24 ժամ, որքան էլ որ գան այլ ահազանգեր։

Նույն սխալը, այլ տեղ

Նույն օրինաչափությունը նաև կրկնապատկել էր ֆոնային աշխատանքի մի մասը. հաշտեցման աշխատանք, որը պահում է յուրաքանչյուր աշխատանքային տարածքի կարգավիճակի մեր գրառումը համաձայն մեր sandbox մատակարարի գրառման։ Յուրաքանչյուր անցում թվարկում է հաշվի բոլոր sandbox-ները՝ արտադրության մեջ հազարավոր, մոտ հինգ վայրկյան, գումարած բոլոր աշխատող կամ դադարած նախագծերը։ Երկու replica-ներն էլ այն գործարկում էին յուրաքանչյուր երկու րոպեն մեկ։

Նրա գրառումները idempotent են, այսինքն՝ երկու անգամ կատարելը նույն արդյունքն է տալիս, ինչ մեկ անգամը, ուստի ոչինչ չէր կոտրվում. պարզապես աշխատանքը կրկնակի էր։ Այժմ յուրաքանչյուր երկու րոպեանոց պատուհան Redis-ում պահպանվում է այնպես, ինչպես մեր օգտագործման չափիչներն են արդեն պահպանում իրենց պատուհանները, և անցումը գործարկում է միայն այն replica-ն, որը պահպանել է այն։ Եթե Redis-ին հասնել չի հաջողվում, անցումը այնուամենայնիվ գործարկվում է. աշխատանքը երկու անգամ կատարելը վնասակար չէ, չկատարելը՝ այո։

Ինչպես ենք փորձարկել

Թեստերը մոդելավորում են իրական կարգավորումը. ահազանգերի մոդուլը բեռնում են երկու անգամ՝ որպես երկու առանձին «replica», երկուսն էլ ուղղում են մեկ համօգտագործվող պահոցի, յուրաքանչյուրից բարձրացնում նույն ահազանգը, ապա բեռնում երրորդ նոր պատճենը՝ «deploy-ից հետո» դերը խաղալու համար, և նորից բարձրացնում այն։ Ուղարկվում է ճիշտ մեկ ահազանգ։ Այլ թեստերը ստուգում են, որ մեկ այլ կառուցողի ահազանգը դեռ գնում է, որ P0-ն ուղարկվում է երկու replica-ներից, և որ ահազանգը դեռ ուղարկվում է, երբ պահոցը անջատված է կամ գերազանցում է ժամանակի սահմանը։ Մաքրման շտկումն ունի իր սեփական թեստը. 24-ժամյա բանալին գոյատևում է 600 այլ ահազանգ, որոնք գալիս են 20 րոպե անց։

Հաշտեցման աշխատանքի համար երկու replica-ները, որոնք միաժամանակ են գործում, գումարած երրորդ անցումը նույն պատուհանում, տալիս են մեկ ցանկ։

Ինչ ենք սա սովորել

  • Հիշողության վիճակը յուրաքանչյուր գործընթացի համար է։ Այն, ինչ պետք է ճշմարիտ լինի սերվերների միջև՝ «ուղարկվել է մեկ անգամ», «աշխատել է մեկ անգամ», պետք է գտնվի այնտեղ, որտեղ նրանք կիսում են։
  • Deploy-ները վերագործարկումներ են։ Վիճակ, որը գոյատևում է միայն մինչև հաջորդ վերագործարկումը, չի գոյատևում սովորական աշխատանքային օրը։
  • Որոշիր, թե ինչ կողմով ձախողվել։ Ահազանգերի դեպքում համօգտագործվող պահոցի անջատվածությունը պետք է նշանակի ավելի շատ ահազանգ, ոչ թե պակաս։
  • Փնտրիր օրինաչափությունը, ոչ միայն օրինակը։ Ահազանգը աղմկոտ դեպքն էր. կրկնապատկված հաշտեցման աշխատանքը նույն սխալն էր, որը անաղմուկ կերպով արժեցնում էր աշխատանք։

Այս ամենից ոչինչ չի երևում Mythex-ի ներսից. ավելին այն մասին, թե ինչպես ենք պահում հարթակը կայուն, տես ինչպես հասանք deploy-ներին զրո 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 简体中文 繁體中文(香港) 繁體中文(台灣)