Deploy များကို 502 error သုညသို့ ဘယ်လိုရောက်ခဲ့သလဲ
Mythex ၏ backend ကို deploy လုပ်တိုင်း 502 Bad Gateway ဖြင့် request အနည်းငယ် ကျရှုံးခဲ့သည်။ အများကြီး မဟုတ်ပါ — သို့သော် deploy အတွင်း 502 ဆိုသည်မှာ တစ်ယောက်၏ click မှာ ဘာမျှ မဖြစ်ခြင်း သို့မဟုတ် ကြည့်နေသော build တစ်ခု ခဏရပ်သွားခြင်း ဖြစ်သည်။ ၎င်းကို ပြဿနာ နှစ်ခုသို့ ခြေရာခံခဲ့သည်: deploy နှင့် တိုက်ပွဲဝင်သော အလိုအလျောက်ပြန်ကောင်းစေသော watchdog တစ်ခု၊ နှင့် server ဘယ်တော့ နားထောင်တာ ရပ်သည် ဆိုသည်နှင့် load balancer ဘယ်တော့ traffic ပို့တာ ရပ်သည် ဆိုသည် အကြား ကွာဟချက်တစ်ခု။ ပြင်ဆင်ပြီးနောက် production deploy သုံးခုဆက်တိုက်တွင် အရေအတွက်သည် ၁၀ မှ ၆ သို့၊ ထို့နောက် ၀ သို့ ရောက်ခဲ့သည်။
စနစ်ပြင်ဆင်ချက်
ကျွန်ုပ်တို့၏ API နှင့် orchestrator သည် AWS Application Load Balancer (ALB) နောက်ရှိ server အုပ်စုငယ်တစ်ခုပေါ်တွင် container အဖြစ် run သည်။ Deploy သည် server တစ်လုံးချင်းစီကို update လုပ်သည်: ဟောင်း container များကို drain လုပ်ပြီး အသစ် စတင်ကာ နောက်တစ်လုံးသို့ သွားသည်။ Server တစ်ခုစီပေါ်ရှိ watchdog က container များ run နေမှု စစ်ဆေးပြီး မရှိသည်ကို ပြန်စတင်သည် — ညသန်းခေါင်တွင် crash ဖြစ်သော process သည် အသုံးပြုသူ နိုးစရာမလိုဘဲ ပြန်ရှိလာရန် ဖြစ်သည်။
ထိုနှစ်ခုစလုံးသည် သီးခြားကြည့်လျှင် ကောင်းသည်။ အတူတကွ မကောင်းပါ။
ပြဿနာ ၁: watchdog က deploy နှင့် ပြိုင်ပြေးခဲ့သည်
Watchdog သည် တစ်မိနစ်တစ်ကြိမ် run ပြီး health check တစ်ကြိမ် ကျရှုံးတိုင်း "ကုသ" သည်။ Deploy သည် ဝန်ဆောင်မှုများကို ရည်ရွယ်ချက်ဖြင့် ၁၅၀ စက္ကန့်အထိ drain လုပ်သည် — ထိုအချိန်တွင် health check ကျရှုံးရန် မျှော်လင့်သည်။ ထို့ကြောင့် watchdog သည် deploy တိုင်း၏ အတွင်းတွင် မီးလောင်သည်။
အများစုအချိန် ၎င်းသည် ပြိုင်ပြေးရာတွင် အန္တရာယ်မရှိ ရှုံးခဲ့သည်။ တစ်ကြိမ် အနိုင်ရခဲ့သည်: deploy အလယ်တွင် compose file (ဘယ် container များ run ရမည်ကို ဖော်ပြသော) ကို ပြန်ရေးခဲ့ပြီး server တစ်လုံးကို gateway container မရှိဘဲ ထားခဲ့သည် — deploy job က အောင်မြင်သည်ဟု အစီရင်ခံခဲ့သော်လည်း။
ပြင်ဆင်ချက်များ:
- Lock တစ်ခုတည်း။ Deploy သည် server ၏ bootstrap script နှင့် တူညီသော file lock ကို ယူသည်၊ ထို့ကြောင့် watchdog နှင့် deploy တို့ တပြိုင်နက် ဘယ်တော့မှ မ run နိုင်ပါ။
- Strike လေးခု၊ တစ်ခုမဟုတ်။ Watchdog သည် မလုပ်မီ health check ကျရှုံးမှု ဆက်တိုက် လေးကြိမ် လိုသည်။ Drain လုပ်နေသော ဝန်ဆောင်မှုသည် သေနေသလို မကြည့်တော့ပါ။
- အရင်းအမြစ်တစ်ခုတည်း။ Compose file သည် servers သို့ ထုတ်ဝေသော အရင်းအမြစ်တစ်ခုတည်းသာ ရှိပြီး ကွဲလွဲနိုင်သော မိတ္တူများ မရှိတော့ပါ။
- စစ်ဆေးပါ၊ ယုံမနေပါနှင့်။ Deploy job သည် command တစ်ခု return ဖြစ်လို့ အောင်မြင်သည်ဟု မဆိုတော့ပါ။ Server တိုင်း၏ API၊ orchestrator၊ gateway နှင့် publish worker ကို အောင်မြင်မည် မတိုင်မီ စစ်ဆေးသည်။
ပြဿနာ ၂: Server က traffic မထွက်ခင် ထွက်သွားခဲ့သည်
ဒုတိယပြဿနာသည် ပိုတိတ်ဆိတ်သည်။ Deploy က server ကို drain လုပ်သောအခါ server သည် health endpoint ကို 503 ဖြင့် ပြန်ဖြေသဖြင့် load balancer က rotation မှ ထုတ်သည်။ ကျွန်ုပ်တို့၏ server သည် ထိုသို့ ၅ စက္ကန့် လုပ်ပြီးမှ ပိတ်သည်။
သို့သော် ALB သည် health ကို အချိန်တစ်ခုခုတွင်သာ စစ်ပြီး target ကို ရပ်ရန် ဆက်တိုက် ကျရှုံးမှု အနည်းဆုံး အကြိမ်အရေအတွက် လိုသည် — အစမှ အဆုံး ~၆၀ စက္ကန့်ခန့်။ ထို့ကြောင့် ~၅၅ စက္ကန့်ခန့်တွင် load balancer သည် နားထောင်ခြင်း ရပ်ပြီးသော server သို့ အမှန်တကယ် request များ ဆက်ပို့နေသည်။ ထိုသည်တို့သည် ကျွန်ုပ်တို့၏ 502 များ ဖြစ်သည်။
ပြင်ဆင်ချက်မှာ အချိန်ဇယား နှစ်ခုကို သဘောတူစေခြင်း ဖြစ်သည်:
- Target group သည် ယခု ၅ စက္ကန့် တိုင်း health စစ်ပြီး ၂ ကြိမ် ကျရှုံးမှ unhealthy ဟု မှတ်သည် — သတိပြုရန် ~၁၀ စက္ကန့်။
- Drain သည် health check ကျရှုံးစပြုသည် နောက် ၁၅ စက္ကန့် အထိ အမှန်တကယ် traffic ကို ဆက်ဝန်ဆောင်သည်၊ ထို့ကြောင့် အမြဲ overlap ရှိသည်။
- ဤ settings များသည် ကလစ်တစ်ကြိမ် နှိပ်ခဲ့သော console တွင် မဟုတ်ဘဲ infrastructure ကို ပံ့ပိုးသော script တွင် ရှိသည်။
နံပါတ်များ တစ်ခုကို တစ်ခု ထိန်းထားစေခြင်း
ဤ timeout များသည် အချင်းချင်း မှီခိုသည်။ Drain သည် balancer သတိပြုရန် လိုသော အချိန်ထက် ရှည်ရမည်; drain နှင့် ပိတ်ခြင်း ပေါင်းပြီး container ကို အတင်းသတ်မည့် ပိတ်ရန် grace period မတိုင်မီ ပြီးရမည်။ လူတစ်ယောက်က ခြောက်လအကြာ နံပါတ်တစ်ခုကို ပြောင်းလျှင် တခြားနံပါတ်များနှင့် မကိုက်ညီဘဲ bug ကို ပြန်ထည့်မိနိုင်သည်။
ထို့ကြောင့် ထိုဆက်စပ်မှုများကို test အဖြစ် ရေးခဲ့သည်: drain သည် health-check interval ကို failure threshold ဖြင့် မြှောက်သော အချိန်ထက် ရှည်ရမည်; ပြန် healthy ဖြစ်ရန် အချိန် တိုနေရမည်; drain တစ်ခုလုံး container ၏ stop grace period အတွင်း ဝင်ရမည်။ နံပါတ်တစ်ခုကို အခြားမရှိဘဲ ပြောင်းလျှင် CI ကျရှုံးသည်။ Test များကိုယ်တိုင်ကိုလည်း mutation-test လုပ်ခဲ့သည် — နံပါတ်တစ်ခုစီကို မှားသော တန်ဖိုးသို့ ပြောင်းပြီး test တစ်ခုက ဖမ်းမိမည်ကို စစ်ခဲ့သည်။
Deploy တိုင်းတာခြင်းမှာ မှားလွယ်သည်
ကျွန်ုပ်တို့၏ ပထမ တိုင်းတာချက်က သန့်ရှင်းသော deploy တစ်ခုသည် ~၃% ပျက်စီးနေသည်ဟု ပြခဲ့သည်။ မဟုတ်ပါ။ 200 မဟုတ်သော တုံ့ပြန်ချက် အားလုံးကို ရေတွက်နေခဲ့သည်၊ drain အတွင်း health endpoint မှ 503 သည် ပျက်ကွက်မှု မဟုတ်ပါ — drain က ၎င်း၏ လုပ်ငန်းကို လုပ်နေခြင်းဖြစ်သည်၊ balancer အား ထို server ကို ရွေးမပေးရန် ပြောနေသည်၊ ထို့နောက်လည်း အမှန်တကယ် request များကို ဆက်ဝန်ဆောင်သည်။
အသုံးပြုသူ ခံစားရသည်မှာ 502 ဖြစ်သည်: request သည် ဘာမှ ရောက်မသွားခဲ့ပါ။ ထိုသည်တို့ကိုသာ ရေတွက်ခြင်းက အမှန်တကယ် ပုံရိပ်ကို ပေးခဲ့သည် — production deploy သုံးခုတွင် ၁၀၊ ၆၊ ၀။
ကျွန်ုပ်တို့ ရရှိခဲ့သည့်အရာ
- Self-healing သည် စီစဉ်ထားသော downtime ကို သိရမည်။ Deploy နှင့် crash ကို မခွဲနိုင်သော watchdog သည် နောက်ဆုံး deploy နှင့် တိုက်ပွဲဝင်မည်။
- Drain သည် လက်ဆွဲနှုတ်ဆက်ခြင်း ဖြစ်သည်။ Server သည် load balancer က traffic မပို့တော့ကြောင်း သက်သေရှိသည်အထိ ဆက်ဝန်ဆောင်ရမည်၊ ထိုအချိန်သတ်မှတ်ချက်ကို server တွင် မဟုတ်ဘဲ balancer တွင် သတ်မှတ်သည်။
- ဆက်စပ်မှု စည်းမျဉ်းများကို test အဖြစ် ရေးပါ။ Operational နံပါတ်များသည် ပြောင်းလဲတတ်သည်။ တစ်ခုနှင့်တစ်ခု ဆက်စပ်ထားသော test များက မပြောင်းပါ။
- တိုင်းတာမည်ကို မတိုင်းမီ ဆုံးဖြတ်ပါ။ "Errors" သည် မှားသော metric ဖြစ်ပြီး "request မှာ ဘာမျှ မရောက်ခဲ့သည်" သည် မှန်သော metric ဖြစ်သည်။
သင် Mythex တွင် အက်ပ် publish လုပ်လျှင် ဤအရာများသည် သင်မမြင်ရပါ — ထိုသည်သည် ရည်ရွယ်ချက် ဖြစ်သည်။ ဆက်စပ်: သင့် publish လုပ်ထားသော အက်ပ် ပြန် publish နေစဉ်လည်း ဘယ်လို ဆက်ရှိသလဲ။