Բլոգ

Ինչպես հասանք deploy-ների զրո 502 սխալի

Մեր backend-ը deploy անելիս մի քանի հարցում ձախողվում էր 502 Bad Gateway-ով։ Ոչ շատ, բայց deploy-ի ընթացքում 502-ը նշանակում է, որ ինչ-որ մեկի սեղմումը ոչինչ չի արել, կամ ինչ-որ build, որ նա դիտում էր, մի պահ կանգնել է։ Մենք այն հետևեցինք երկու առանձին խնդրի․ ինքնաբուժող watchdog, որ կռվում էր մեր deploy-ների դեմ, և բացը այն պահի միջև, երբ սերվերը դադարում է լսել, և երբ load balancer-ը դադարում է նրան երթևեկություն ուղարկել։ Շտկումներից հետո արտադրության երեք հաջորդական deploy-ի ընթացքում թիվը իջավ 10-ից 6-ի, իսկ հետո՝ 0-ի։

Կարգավորումը

ԱPI-ն և orchestrator-ը աշխատում են որպես կոնտեյներներ սերվերների փոքր խմբում, AWS Application Load Balancer-ի (ALB) հետևում։ Deploy-ը թարմացնում է մեկ սերվեր մեկ անգամ․ դադարեցնում է հին կոնտեյներները, գործարկում նորերը և անցնում հաջորդին։ Յուրաքանչյուր սերվերի վրա watchdog-ը ստուգում է, որ կոնտեյներները բարձրացած են, և վերամեկնարկում է ցանկացած, որ չի աշխատում։ Այն գոյություն ունի, որպեսզի գիշերային 3-ին խափանված պրոցեսը վերադառնա, առանց որևէ մեկին արթնացնելու։

Ամենք առանձին ողջամիտ են։ Միասին՝ ոչ։

Խնդիր 1․ watchdog-ը մրցեց deploy-ի հետ

Watchdog-ը աշխատում էր րոպեն մեկ անգամ և «բուժում» էր մեկ ձախողված առողջության ստուգումից հետո։ Deploy-ը միտումնավոր դադարեցնում է ծառայությունները մինչև 150 վայրկյան՝ այդ ընթացքում առողջության ստուգումը պետք է ձախողվի։ Ուստի watchdog-ը գործարկվում էր յուրաքանչյուր deploy-ի ժամանակ։

Այն մեծամասամբ անվնաս կորցնում էր մրցումը։ Մեկ անգամ շահեց․ deploy-ի մեջտեղում վերագրեց compose ֆայլը (նկարագրությունը, թե որ կոնտեյներները պետք է աշխատեն) և թողեց սերվերը առանց gateway կոնտեյների ընդհանրապես՝ միաժամանակ deploy աշխատանքը հայտնում էր հաջողություն։

Շտկումները․

  • Մեկ կողպեք։ Deploy-ն այժմ վերցնում է նույն ֆայլի կողպեքը, ինչ սերվերի bootstrap սկրիպտը, ուստի watchdog-ը և deploy-ը երբեք չեն աշխատում միաժամանակ։
  • Չորս հարված, ոչ մեկ։ Watchdog-ը պահանջում է չորս հաջորդական ձախողված ստուգում, նախքան գործելը։ Ժամանակավորապես դադարեցվող ծառայությունը այլևս մեռած չի թվում։
  • Մեկ սահմանում։ Compose ֆայլն այժմ ունի ճիշտ մեկ աղբյուր, որը հրապարակվում է սերվերներին, այլ ոչ թե պատճեններ, որոնք կարող էին շեղվել։
  • Ստուգել, ոչ թե վստահել։ Deploy աշխատանքը այլևս չի անցնում, որովհետև հրամանը վերադարձել է։ Այն ստուգում է յուրաքանչյուր սերվերի API-ն, orchestrator-ը, gateway-ը և հրապարակման աշխատողը, նախքան հաջողության հասնելը։

Խնդիր 2․ սերվերը հեռացավ, նախքան երթևեկությունը

Երկրորդ խնդիրն ավելի անաղմուկ էր։ Երբ deploy-ը դադարեցնում է սերվերը, սերվերը սկսում է պատասխանել իր առողջության endpoint-ին 503-ով, որպեսզի load balancer-ը այն դուրս բերի շրջանառությունից։ Մերը դա անում էր 5 վայրկյան, ապա անջատվում։

Բայց ALB-ը առողջությունը ստուգում էր միայն երբեմն և պահանջում էր մի քանի ձախողված ստուգում հաջորդաբար, նախքան թիրախին երթևեկությունը դադարեցնելը՝ մոտ 60 վայրկյան ընդհանուր։ Այսպիսով, մոտ 55 վայրկյան, load balancer-ը շարունակում էր իրական հարցումներ ուղարկել սերվերին, որը արդեն դադարել էր լսել։ Դրանք էին մեր 502-երը։

Շտկումը երկու ժամանակացույցները համաձայնեցնելն էր․

  • Թիրախային խումբը ստուգում է յուրաքանչյուր 5 վայրկյան և թիրախը անառողջ է նշում 2 ձախողումից հետո՝ մոտ 10 վայրկյանում նկատելու համար։
  • Դադարեցումը շարունակում է սպասարկել իրական երթևեկությունը 15 վայրկյան այն բանից հետո, երբ սկսում է ձախողել առողջության ստուգումները, ուստի միշտ կա համընկում։
  • Այս կարգավորումները ապրում են ենթակառուցվածքը տրամադրող սկրիպտում, ոչ թե մի կոնսոլում, որ ինչ-որ մեկը մի անգամ սեղմել է։

Թվերը միմյանց պահել

Նման ժամանակային սահմանները միմյանց են կախված։ Դադարեցումը պետք է ավելի երկար լինի, քան balancer-ին անհրաժեշտ ժամանակը նկատելու համար․ դադարեցումը գումարած անջատումը պետք է ավարտվեն, մինչև կոնտեյները ստիպողաբար չսպանվի։ Հեշտ է, որ ինչ-որ մեկը վեց ամսից փոխի մի թիվ և անշուշտ վերադարձնի սխալը։

Ուստի այդ կապերը գրել ենք որպես թեստեր․ դադարեցումը պետք է լինի ավելի երկար, քան առողջության ստուգման ընդմիջումը՝ բազմապատկած ձախողման շեմով․ առողջ վերադառնալու ժամանակը պետք է մնա կարճ․ ամբողջ դադարեցումը պետք է տեղավորվի կոնտեյների կանգնեցման սպասման ժամանակի մեջ։ Փոխեք մի թիվ՝ առանց մյուսների, և CI-ը ձախողվում է։ Մենք նաև թեստավորեցինք թեստերը՝ յուրաքանչյուր թիվ փոխելով սխալ արժեքի և ստուգելով, որ թեստը բռնում է այն։

Չափելը հեշտ է սխալվել

Մեր առաջին չափումը ասաց, որ մաքուր deploy-ը մոտ 3% կոտրված է։ Դա չէր։ Մենք հաշվում էինք 200-ից տարբեր յուրաքանչյուր պատասխան, իսկ առողջության endpoint-ից դադարեցման ընթացքում 503-ը ձախողում չէ․ դա դադարեցման աշխատանքն է, որ ասում է balancer-ին չընտրել այդ սերվերը, մինչ այն շարունակում է սպասարկել իրական հարցումները։

Օգտատերը զգում է 502-ը․ հարցումը ոչ մի տեղ չհասավ։ Միայն դրանք հաշվելը տվեց իրական պատկերը՝ 10, ապա 6, ապա 0՝ երեք արտադրական deploy-ի ընթացքում։

Ինչ սովորեցինք

  • Ինքնաբուժումը պետք է իմանա պլանավորված պարապուրդի մասին։ Watchdog-ը, որ չի կարող տարբերել deploy-ը խափանումից, ի վերջո կկռվի deploy-ի հետ։
  • Դադարեցումը ձեռքսեղմում է։ Սերվերը պետք է շարունակի սպասարկել, մինչև load balancer-ը ապացուցված կերպով դադարի երթևեկություն ուղարկել, և այդ ժամանակացույցը սահմանվում է balancer-ի վրա, ոչ սերվերի։
  • Ինվարիանտները կոդավորեք թեստերով։ Գործառնական թվերը շեղվում են։ Թեստերը, որ դրանք միմյանց հետ կապում են, չեն շեղվում։
  • Որոշեք, թե ինչ եք չափում, նախքան չափելը։ «Սխալները» սխալ չափանիշ էր․ «հարցումները, որ ոչինչ չհասան» ճիշտն էր։

Եթե հրապարակում եք հավելված Mythex-ում, սա ոչ մի կերպ տեսանելի չէ ձեզ համար՝ և դա է կետը։ Առնչվող․ ինչպես է ձեր հրապարակված հավելվածը մնում ակտիվ, երբ նորից եք հրապարակում։

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 简体中文 繁體中文(香港) 繁體中文(台灣)