Publish-ийг хоёр удаа дарахад одоо нэг л удаа нийтэлнэ
Нэг аппын гурван publish хүсэлт манай API-д 84 миллисекундын зайтай ирж, тус бүр тэр аппын бүтэн deploy эхлүүлсэн. Тэд ижил hosting дээр зэрэг орж, үүссэн хувилбаруудын хэд нь аль хэдийн өөр нэг нь орсон учраас амжилтгүй болсон, харагдах цорын ганц тэмдэг нь «release failed» гэсэн имэйл байв — аппынх өөрөө эцэстээ сайн байсан. Одоо нэг аппын publish явж байхад ирсэн өөр publish шинэ build эхлүүлдэггүй. Өгөгдлийн сан аль хүсэлт амжилттай болохыг шийдэж, бусад нь үнэнийг авдаг: publish аль хэдийн явж байна.
Юу болсон бэ
Та аппаа publish хийхэд API deployment бичлэг үүсгэж, манай orchestrator-оос — build-ийг ажиллуулдаг үйлчилгээ — тэр аппыг build хийж нийтлэхийг хүсдэг. Publish нь Publish товчноос, өөр браузерийн табаас, эсвэл та нийтлэхийг хүсэхэд агентаас эхэлж болно. Давхар дарах, хоёр таб, эсвэл хоёр удаа ирсэн агентын хүсэлт бүгд ойролцоогоор нэг мөчид нэг аппын хэд хэдэн publish үүсгэж болно.
Энэ тохиолдолд гурав нь 84 мс дотор ирсэн. Тус бүр бүтэн deploy ажиллуулсан. Hosting платформ дээр нэг аппын release-ууд нэг секундэд үүссэн, гурван нь өөр нь аль хэдийн явж байгаа учраас амжилтгүй болсон. Сүүлийн нэг нь гацсан, дараа нь апп ажилласан.
Яг энэ нь олоход хялбар болгосон: хэрэглэгч нэг ажиллаж буй апп харсан. Алдаанууд зөвхөн release-ын амжилтгүйн имэйлд харагдсан.
Яагаад юу ч зогсоосонгүй вэ
Publish кодонд төслийн явж буй deploy-уудыг харах алхам байсан. Гэвч тэр юу хийдэг вэ гэвэл эхлэхээсээ өмнө явж буй deploy бүрийг амжилтгүй гэж тэмдэглэдэг байсан — «шинэ publish-оор орлуулагдсан». Тэр нь үхсэн процессын үлдээсэн build-уудыг цэвэрлэх зорилготой байсан.
Практикт, build явж байхад ирсэн хоёр дахь publish нь эхнийг үхсэн гэж зарлаад өөрийнхөө build-ийг эхлүүлдэг байсан. Хоёулаа ижил аппад дуусах хүртэл ажилласан. Түгжээ байгаагүй; race-ийг нээдэг алхам л байсан.
Нэг аппын анхны publish-д хоёр дахь, илүү хачин шинж тэмдэг байсан. Deployment бичлэг дахин ашиглах боломжгүй үед, хоёр зэрэг анхны publish хоёулаа нэгийг оруулахыг оролддог байсан. Өгөгдлийн санд аппын линкийн нэр (slug, жишээ нь your-app.mythex.ai-ийн your-app) дээр unique индекс байдаг тул хоёр дахь оруулга амжилтгүй болсон. API үүнийг «тэр линкийн нэр авагдсан» гэж орчуулсан — хэрэглэгчид нэрээ солихыг зөвлөж, гэтэл тэр мөчид тэр нэрээр амжилттай нийтэлж байсан аппыг.
Засвар: түгжээ нь нэхэмжлэл
Deployment бичлэгийг нэхэмжлэх одоо нэг нөхцөлт өгөгдлийн сангийн шинэчлэлт: тэр мөрийг building гэж тэмдэглэ зөвхөн хэн ч нийтэлж байхгүй бол. Энэ нь нэг statement тул өгөгдлийн сан нэг миллисекундэд ирсэн хүсэлтүүдийг шийддэг. Яг нэг нь мөрийг өөрчилдөг. Бусад нь 0 мөр өөрчлөгдсөнийг хараад зогсож, orchestrator руу хэзээ ч хүрдэггүй.
Түгжээнд эзэмшигч нь үхвэл гарах арга хэрэгтэй. Хэрэв API publish дундуур дахин эхэлбэл мөр «building» хэвээр үлдэж, апп хэзээ ч нийтлэгдэхгүй болно. Тиймээс зүрхний цохилт (heartbeat) тасарсан мөрийг дахин нэхэмжилж болно — ажиллаж буй publish мөрийг 30 секунд тутам шинэчилдэг, таван минут чимээгүй байвал үхсэн гэж тооцно. Энэ босго нь heartbeat-аас гардаг, build хэр удаан үргэлжлэх тухай таамаглал биш. Хэрэглэгчийн өөрийн Dockerfile-ийг build хийх нь хууль ёсоор удаан үргэлжилж болно, мөн heartbeat хийж байгаа удаан build нь нэхэмжлэлээ хадгалдаг.
Пublish-ийн өмнө in-progress deploy-уудыг амжилтгүй болгодог алхам одоо явахгүй. Зөвхөн үхсэн процессын үлдээсэн мөрүүд цэвэрлэгдэнэ.
Ялагдсан хүсэлтэд үнэнийг хэлэх
Ялагдсан хүсэлт одоо тодорхой хариулт авдаг: publish_in_progress, мөн ажиллаж буй deployment-ийн ID-тай хамт. Publish эхлүүлж болох газар бүр үүнийг зохицуулдаг:
- Ажлын талбар аль хэдийн ажиллаж буй build-ийг дагадаг, түүний дээр алдаа харуулахын оронд.
- Агент аппын publish аль хэдийн явж байгааг мэдэж, хүлээхийг хэлдэг, харин өмнө нь «амжилтгүй» гэж хэлдэг байсан тул Dockerfile-ийг «засаж» дахин оролдох зам руу явуулж болдог байв.
- Линкийн нэрний анхны publish-ийн мөргөлдөөн шалгагддаг: хэрэв нэрийг эзэмшиж буй мөр тэр төслийн өөрийн ажиллаж буй publish бол хариулт нь «аль хэдийн нийтэлж байна», харин «тэр нэр авагдсан» биш. Бусад төсөлтэй жинхэнэ мөргөлдөөн нэр солих мессежээ хэвээр авна.
Бид яаж шалгасан бэ
Бид нэг аппын гурван publish-ийг жинхэнэ өгөгдлийн сан болон хуурамч orchestrator дээр зэрэг ажиллуулж, орchestrator-оос хэдэн deploy хүссэнийг тоолдог нөхөн үйлдвэрлэх скрипт бичсэн. Энэ нь анхны publish болон амьд апп дахин publish хийхийг хамардаг. Засахаас өмнө хоёр deploy тоологддог байсан. Дараа нь нэг.
Скрипт мөн гарц-ыг хамардаг: апп мөрийг 10 минут heartbeat-гүй building гэж тэмдэглэж, дахин publish хийж, шинэ publish мөрийг нэхэмжилж ажиллахыг шалгана.
Нэгжийн тестүүд түгжээг хоёр зүйлд барьдаг: зэрэг гурван дахин publish-ийн дотроос яг нэг нь орж, нөгөө хоёр нь publish явж байна гэж хэлэгдэнэ; мөн эзэмшигч нь үхсэн build-ийг нэхэмжилж болно. Өөр тест шинэ оролдлого өмнөх оролдлогын алдааны мессежийг авч явдаггүйг шалгадаг.
Бидний авсан дүгнэлт
- Цэвэрлэх код нь далд race байж болно. «Явж буй бүгдийг амжилтгүй болгоод дараа нь эхлэх» нь эрүүл ахуй мэт харагддаг. Хоёр дуудагчтай бол тус бүр нөгөөгөө цуцалдаг.
- Өгөгдлийн санд шийдүүлэх. Унших, дараа нь бичих нь өөр хүсэлтэд цоорхой үлдээдэг. Нэг нөхцөлт шинэчлэлт үлддэггүй.
- Түгжээ бүр heartbeat-тай холбогдсон хугацаатай байх ёстой. Үгүй бол бүх crash нь гацсан аппад хүрдэг.
- Алдааны мессеж бол заавар. «Тэр нэр авагдсан» нь хүмүүст буруу зүйл хийхийг хэлсэн. Зөв мессеж илүү энгийн, үнэн байсан.
Hosting дээрх publish-ийн талаар docs-д: хэрхэн publish хийх вэ. Холбоотой засвар: таны нийтлэгдсэн апп шинэчлэх явцдаа ажиллаж байдаг.