การจับแอปที่ขัดข้องทันทีหลัง publish
เมื่อวันที่ 25 กันยายน การ publish สามครั้งถูกทำเครื่องหมายว่าสำเร็จ ทั้งที่ API ของแอปขัดข้องไม่กี่วินาทีหลังบูตทุกครั้ง เพราะการ publish "สำเร็จ" rollback จึงไม่ทำงาน การตรวจสอบเบื้องหลังล้มเหลวพวกมันหลายนาทีต่อมา และเว็บไซต์ทั้งหมดกลายเป็น 404 health check กำลังนับการขัดข้องจากรายการเหตุการณ์ของแพลตฟอร์มโฮสติ้ง ซึ่งเก็บเพียงห้าเหตุการณ์ล่าสุดต่อเครื่อง การวนขัดข้องทำให้รายการเต็มเสมอ และการนับจึงไม่เคยเพิ่มขึ้น ตอนนี้มันเปรียบเทียบเวลาของการขัดข้องล่าสุดแทน และการ publish ที่วนขัดข้องจะล้มเหลวและกู้เวอร์ชันก่อนหน้ากลับมา
การ publish รอให้อะไร
เมื่อคุณ publish แอปที่มี backend บน Mythex เวอร์ชันใหม่จะถูกติดตั้งลงบนเครื่องของแพลตฟอร์มโฮสติ้ง และ health check จะตัดสินว่าการ publish ขึ้นออนไลน์หรือล้มเหลว หากล้มเหลว rollback จะคืนเวอร์ชันก่อนหน้า
ส่วนที่ยากคือ "เริ่มทำงานแล้ว" ไม่เท่ากับ "กำลังให้บริการ" แพลตฟอร์มรายงานว่าเครื่องเริ่มทำงานแล้วทันทีที่มันขึ้น แอปที่ขัดข้องหนึ่งวินาทีหลังบูตจะถูกรีสตาร์ตทันที และไม่กี่วินาทีต่อมาก็ถูกอ่านว่าเริ่มทำงานอีกครั้ง ดังนั้น health check จึงซับซ้อนขึ้นตามเวลา เป็นสามชั้น:
- ดูสองครั้ง หลังจากเครื่องถูกอ่านว่าเริ่มทำงานแล้ว ให้รอสักครู่แล้วดูอีกครั้ง การขัดข้องตอนบูตมักทำให้การดูครั้งที่สองล้มเหลว
- เฝ้าระวังการวนขัดข้อง หากแพลตฟอร์มรายงานว่าเครื่องขัดข้องซ้ำๆ และมันหยุดรีสตาร์ตแล้ว ให้ล้มเหลว
- นับการขัดข้องนับตั้งแต่การ publish เริ่ม การดูสองครั้งอาจคร่อมการรีสตาร์ตได้ ดังนั้นหากมีการขัดข้องใดๆ เกิดขึ้นนับตั้งแต่การ publish เริ่ม ให้ดูครั้งที่สาม และหากการขัดข้องมีมากกว่าการดูครั้งก่อน แอปไม่ได้ทำงานต่อเนื่อง
การตรวจสอบข้อที่สามคือสิ่งที่ล้มเหลวในครั้งนี้
ทำไมการนับจึงคงที่
ข้อมูลการขัดข้องมาจากรายการเหตุการณ์ของแต่ละเครื่อง ได้แก่ การเริ่ม การออก และการรีสตาร์ต แพลตฟอร์มเก็บเพียงห้าเหตุการณ์ล่าสุดต่อเครื่อง
ลองนึกภาพแอปที่ขัดข้องหลังบูตไปแล้ว 2.5 วินาทีทุกครั้ง ดังที่หนึ่งในนั้นเป็น ทุกรอบเพิ่มการขัดข้องหนึ่งครั้งและการเริ่มหนึ่งครั้ง หลังจากผ่านไปสองสามรอบ รายการก็เต็ม และตั้งแต่นั้นเป็นต้นไป เหตุการณ์ใหม่แต่ละเหตุการณ์จะดันเหตุการณ์เก่าออกไป รายการเลื่อนไปข้างหน้า แต่มันจะมีสัดส่วนประมาณเดิมเสมอ คือมีการขัดข้องสองสามครั้งและการเริ่มสองสามครั้ง
ดังนั้น "มีการขัดข้องกี่ครั้งนับตั้งแต่การ publish เริ่ม" จึงคืนค่าเท่าเดิมทุกการดู การดูครั้งที่สองเห็นการขัดข้องสองครั้ง เช่น และการดูครั้งที่สามก็เห็นสองครั้งเช่นกัน แม้จะเป็นการขัดข้องคนละครั้งก็ตาม การตรวจสรุปว่าการขัดข้องหยุดแล้ว และผ่านการ publish
สิ่งนั้นเกิดขึ้นสามครั้งในวันที่ 25 กันยายน ในสองแอป ในแต่ละครั้ง:
- การ publish ถูกทำเครื่องหมายว่าใช้งานได้แล้ว
- rollback ไม่ทำงาน เพราะไม่มีอะไรล้มเหลว
- reconciler ของเรา ซึ่งเป็น background job ที่ตรวจ deployment หลังเกิดเหตุการณ์ ทำให้ deployment ล้มเหลวหลายนาทีต่อมา
- และเว็บไซต์ทั้งหมดคืน 404
การ publish ที่ล้มเหลวตรงเวลาสามารถกู้คืนได้ rollback จะคืนเวอร์ชันก่อนหน้า แต่การ publish ที่ล้มเหลวหลายนาทีหลังจากถูกประกาศว่าสำเร็จ ได้ข้าม rollback ไปแล้ว
เราพบได้อย่างไร
เราทำซ้ำปัญหาในเครื่อง: นำ API ที่ทำงานอยู่ ปล่อยให้มันหลับ แล้ว publish ซ้ำด้วยการเปลี่ยนแปลงที่ขัดข้องตอนบูต health check ทำเครื่องหมายว่าใช้งานได้
สิ่งนี้ตรงกับโปรดักชัน ในการ publish แต่ละครั้งทั้งสามครั้ง แอปตายภายในไม่กี่วินาทีของการบูตทุกครั้ง แต่จำนวนการขัดข้องที่ check เปรียบเทียบไม่เคยเพิ่มขึ้นระหว่างการดู
วิธีแก้: เปรียบเทียบการขัดข้องล่าสุด ไม่ใช่จำนวน
แทนที่จะนับการขัดข้อง ตอนนี้ check ดูเวลาของการขัดข้องล่าสุดนับตั้งแต่การ publish เริ่ม
หากการดูครั้งที่สองแสดงว่ามีการขัดข้องใดๆ นับตั้งแต่การ publish เริ่ม check จะรอและดูครั้งที่สาม หากการขัดข้องล่าสุดในการดูครั้งที่สามอยู่หลังการขัดข้องล่าสุดในการดูครั้งที่สอง เครื่องขัดข้องซ้ำระหว่างนั้น มันไม่ได้ทำงานต่อเนื่อง และการ publish ล้มเหลวพร้อมข้อความว่าเครื่องขัดข้องซ้ำๆ นับตั้งแต่การ publish และยังคงรีสตาร์ตอยู่
วิธีนี้ใช้ได้ไม่ว่ารายการเหตุการณ์จะสั้นแค่ไหน หน้าต่างเลื่อนห้าเหตุการณ์อาจซ่อนจำนวนการขัดข้องได้ แต่ไม่สามารถซ่อนว่ามีการขัดข้องใหม่เพิ่งเกิดขึ้นได้ เพราะเหตุการณ์ล่าสุดคือสิ่งที่ยังคงเก็บไว้เสมอ
ด้วยการเปลี่ยนแปลงนี้ การทำซ้ำในเครื่องทำงานถูกต้อง: การ publish ล้มเหลว และ image ก่อนหน้าถูกกู้คืน นอกจากนี้ยังมี test ที่จำลองพฤติกรรมของแพลตฟอร์ม ทุกการดูเพิ่มการขัดข้องหนึ่งครั้งและการเริ่มหนึ่งครั้ง และตัดรายการให้เหลือห้า แล้วตรวจว่าคำตัดสินเป็นความล้มเหลว ไม่ใช่การผ่าน
สิ่งที่เราได้เรียนรู้
- รู้รูปร่างของข้อมูลที่คุณนับ การนับบนรายการที่มีขีดจำกัดจะหยุดมีความหมายเมื่อรายการเต็ม ขีดจำกัดนั้นไม่ได้ซ่อนไว้ เราเพียงยังไม่ได้ออกแบบ check ให้คำนึงถึงมัน
- ให้ความสำคัญกับคำถาม "มีอะไรใหม่เกิดขึ้นหรือไม่" มากกว่า "เกิดขึ้นกี่ครั้ง" เวลาประทับล่าสุดคงอยู่รอดหลังการตัดทอน ผลรวมไม่รอด
- ความล้มเหลวที่ช้าเป็นสิ่งที่แย่กว่าความล้มเหลวที่เร็ว บิลด์ที่พังเดียวกันไม่เป็นอันตรายหากการ publish ล้มเหลวและ rollback แต่จะทำให้เว็บไซต์ล่มหากถูกประกาศว่าสำเร็จก่อน
- ทำซ้ำด้วยเงื่อนไขจริง บั๊กนี้ต้องการเครื่องที่ขัดข้องมาพอจนรายการเหตุการณ์ของมันเต็มแล้ว การขัดข้องเร็วครั้งเดียวในการทดสอบจะไม่แสดงมัน
การแก้ไขนี้คู่กับอีกการแก้ไขจากวันเดียวกัน ซึ่งทำให้ rollback คืนเวอร์ชันเก่ากลับมาแทนที่จะลบมัน: การ republish ที่ล้มเหลวไม่เคยลบ backend ที่ทำงานอยู่ หากแอปของคุณ publish ไม่สำเร็จเพราะมันขัดข้องตอนเริ่ม เอกสารการแก้ปัญหาการ publish และคู่มือของเราเรื่อง การดีบักแอปที่ AI สร้าง เป็นจุดเริ่มต้นที่ดี