Deploy-ийн 502 алдааг нуля болгосон нь яаж вэ
Mythex-ийн backend-ийг deploy хийх бүрт хэдэн хүсэлт 502 Bad Gateway алдаа авдаг байв. Тоо нь их биш — гэхдээ deploy-ийн үед 502 гэдэг нь хэн нэгний дарсан товч юу ч хийгээгүй, эсвэл тэр харж байсан build хэсэг зогссон гэсэн үг. Бид үүнийг хоёр тусдаа асуудалд хөтөлсөн: deploy-тэй тэмцдэг өөрийгөө засдаг watchdog, мөн сервер сонсохоо больсны ба load balancer тэр рүү траффик явуулахаа больсны хооронд гарсан зай. Засварын дараа үйлдвэрлэлийн гурван дараалсан deploy-ийн тоо 10-аас 6, 6-аас 0 болсон.
Тохиргоо
Бидний API болон orchestrator нь AWS Application Load Balancer (ALB)-ийн ард жижиг серверийн бүлэгт контейнер хэлбэрээр ажилладаг. Deploy нэг сервер нэг сервераар шинэчилдэг: хуучин контейнеруудыг drain хийж, шинэ контейнер эхлүүлээд, дараагийн рүү шилжинэ. Сервер бүр дээрх watchdog контейнеруудыг ажиллаж байгааг шалгаж, ажиллахгүй байгаа аливааг дахин эхлүүлдэг — шөнө 3 цагт унасан процесс хэн ч сэрэлгүйгээр эргэж ирэхийн тулд байдаг.
Эдгээр хоёр нь тус тусдаа зохистой боловч хамтдаа зохисгүй байсан.
Асуудал 1: watchdog deploy-тэй уралдсан
Watchdog минут тутамд ажиллаж, нэг амжилтгүй эрүүл байдлын шалгалтын дараа «засдаг» байв. Deploy нь үйлчилгээг 150 секунд хүртэл санаатай drain хийдэг — тэр хугацаанд эрүүл байдлын шалгалт бүтэлгүйтэх ёстой. Тиймээс watchdog deploy бүрийн үед ажилладаг байв.
Ихэвчлэн тэр уралдаанд хор хөнөөлгүй ялагдаж байсан. Нэг удаа тэр ялсан: deploy-ийн дундуур compose файлыг (аль контейнерууд ажиллах ёстойг тодорхойлдог файл) дахин бичиж, серверт gateway контейнер огт үлдээсэн — deploy job амжилттай гэж тайлагнаж байхад.
Засвар:
- Нэг түгжээ. Deploy одоо серверийн bootstrap скриптийн ижил файлын түгжээг авдаг, тиймээс watchdog болон deploy хэзээ ч зэрэг ажиллахгүй.
- Дөрвөн удаа, нэг биш. Watchdog үйлдэл хийхээс өмнө дараалсан дөрвөн эрүүл байдлын шалгалт бүтэлгүйтэх ёстой. Drain хийж буй үйлчилгээ одоо үхсэн мэт харагдахгүй.
- Нэг тодорхойлолт. Compose файл одоо серверүүдэд нийтлэгддэг нэг эх сурвалжтай, хуулбарууд нь зөрөхөөс сэргийлдэг.
- Итгэхгүй, баталгаажуул. Deploy job одоо команд буцсан гэдгээр амжилттай гэж тооцогдохгүй. Амжилтад хүрэхээс өмнө сервер бүрийн API, orchestrator, gateway, publish worker-ийг шалгадаг.
Асуудал 2: сервер трафикаас өмнө явсан
Хоёр дахь асуудал илүү нууц байсан. Deploy сервер drain хийх үед сервер эрүүл байдлын endpoint-доо 503 хариулж эхэлдэг, ингэснээр load balancer түүнийг эргэлтээс гаргадаг. Бидний сервер ингэж 5 секунд хариулж, дараа нь унтардаг байв.
Гэвч ALB эрүүл байдлыг тодорхой завсраар шалгадаг бөгөөд target-ийг зогсоохын өмнө дараалсан хэдэн удаагийн алдаа шаарддаг — нийт 60 секунд орчим. Тиймээс ойролцоогоор 55 секундын турш load balancer аль хэдийн сонсохоо больсон сервер рүү бодит хүсэлт илгээсээр байсан. Тэр бол бидний 502-ууд байв.
Засвар бол хоёр цагийн хуваарийг зохицуулах байв:
- Target group одоо 5 секунд тутам шалгаж, 2 алдааны дараа target-ийг эрүүл бус гэж тэмдэглэдэг — мэдэхэд ойролцоогоор 10 секунд.
- Drain эрүүл байдлын шалгалтад алдаа гарч эхлээд 15 секундын турш бодит траффикийг үйлчилсээр байна, ингэснээр үргэлж давхцал байна.
- Эдгээр тохиргоо нь консол дээр нэг удаа дарсан хүний биш, инфраструктурыг бэлтгэдэг скриптэд байна.
Тоонууд бие биенээ хангахуйц байлгах
Ийм timeout-ууд бие биенээсээ хамаардаг. Drain нь balancer-ийн мэдэх хугацаанаас урт байх ёстой; drain плюс унтралт контейнерийг хүчээр устгахаас өмнө дуусах ёстой. Хэн нэгэн зургаан сарын дараа нэг тоог өөрчлөөд, алдааг чимээгүйхэн эргүүлж оруулах нь амархан.
Тиймээс бид эдгээр хамаарлыг тест болгон бичсэн: drain нь эрүүл байдлын шалгалтын завсар үржүүлэх босго-оос урт байх ёстой; дахин эрүүл гэж тэмдэглэгдэх хугацаа богино хэвээр байх ёстой; бүх drain контейнерийн зогсох хугацааны дотор багтах ёстой. Нэг тоог бусадгүйгээр өөрчилбөл CI унана. Бид тестүүдийг өөрсдийгөө мутацийн тест хийсэн — тоо бүрийг буруу утгад өөрчлөөд, тест барьж байгааг шалгасан.
Deploy хэмжихэд хэцүү
Манай анхны хэмжилт цэвэр deploy ойролцоогоор 3%-ийн эвдрэлтэй гэж хэлсэн. Тийм биш байсан. Бид 200-гүй хариу бүрийг тоолж байсан, харин drain-ийн үед эрүүл байдлын endpoint-ээс ирсэн 503 бол алдаа биш — drain өөрийн ажлаа хийж байгаа, load balancer-д тэр серверийг сонгохгүй байхыг хэлж, харин бодит хүсэлтүүдийг үргэлжлүүлэн үйлчилж байна.
Хэрэглэгч мэдэрдэг зүйл бол 502: хүсэлт юу ч хүрээгүй. Зөвхөн тэдгээрийг тоолоход бодит зураг гарсан — гурван үйлдвэрлэлийн deploy-ийн турш 10, дараа нь 6, дараа нь 0.
Бидний авсан дүгнэлт
- Өөрийгөө засдаг систем төлөвлөсөн зогсолтыг мэдэх ёстой. Deploy-оос crash-ыг ялгаж чаддаггүй watchdog эцэстээ deploy-тэй тэмцэх болно.
- Drain бол гар барилт. Сервер load balancer траффик илгээхээ больсныг баталгаатай мэдэх хүртэл үйлчилсээр байх ёстой, мөн тэр хугацаа нь сервер дээр биш balancer дээр тохирогддог.
- Инвариантуудыг тест болгон кодло. Үйл ажиллагааны тоо хазайдаг. Бие биетэйгээ холбосон тестүүд хазайдаггүй.
- Хэмжихээсээ өмнө юуг хэмжиж байгаагаа шийд. «Алдаа» буруу метрик байсан; «хүсэлт юу ч хүрээгүй» зөв метрик байсан.
Хэрэв та Mythex дээр нийтлэгдсэн апп бүтээж байвал энэ нь танд харагдахгүй — энэ л зорилго. Холбоотой: нийтлэгдсэн аппаа дахин нийтлэх явцдаа хэрхэн ажиллуулсаар байдаг вэ.