Node.js Worker: วิธีแก้ปัญหา Background Queue วนซ้ำไม่หยุด
เจาะลึกการแก้ไขปัญหา Node.js worker วนลูป retry ไม่หยุด พร้อมเทคนิคจัดการ dead-letter queue และจำกัดจำนวนความพยายามอย่างแม่นยำ

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
- ปัญหา retry loop บั่นทอนระบบและทำให้ข้อความเก่าค้างในคิว
- กำหนดงบประมาณความพยายามจำกัดและคัดแยกข้อผิดพลาดถาวร
- แยกสถานะการขนส่งในคิวออกจากสถานะความสำเร็จทางธุรกิจจริง
- ทดสอบผลลัพธ์ 3 แบบและจำกัดอัตราเรดไรฟก่อนโรลเอาต์จริง
ปัญหาลูปการลองใหม่ (retry loop) ถือเป็นปัญหาความพร้อมใช้งานของระบบก่อนที่จะเป็นเพียงแค่เรื่องของการตั้งค่าคิว เพราะมันสามารถดึงเอาช่องทำงานทั้งหมดไปใช้กับงานที่ไม่วันสำเร็จ พร้อมทั้งเพิ่มอายุของข้อความที่ควรจะปกติ คำตอบสั้น ๆ คือ ให้งานเบื้องหลังแต่ละชิ้นมีงบประมาณความพยายามที่จำกัด จัดประเภทความล้มเหลวแบบถาวรก่อนจะกำหนดรอบการส่งใหม่ และเก็บระบบกู้คืน dead-letter queue ไว้เป็นปฏิบัติการที่ควบคุมโดยผู้ดูแลระบบ สำหรับ worker ของ Node.js ที่มีการลองใหม่ไม่หยุด เริ่มต้นด้วยการพิสูจน์ให้ได้ว่าตัวนับตัวไหนกำลังเพิ่มขึ้น เนื่องจากตัวโบรกเกอร์ ไลบรารีของ worker และโค้ดแอปพลิเคชันต่างก็สามารถรักษาค่าตัวนับที่แตกต่างกันได้
การถอยหลังทิ้งช่วง (backoff) จะเปลี่ยนไปเมื่อแต่งานส่งผลลัพธ์กลับมา แต่มันไม่ได้เป็นตัวตัดสินใจว่างานควรหยุดส่งกลับมา การติดตามข้อความหนึ่งข้อความไปตลอดเส้นทางก่อนที่จะเปลี่ยนการตั้งค่าจำนวนความพยายามสูงสุดเป็นสิ่งจำเป็น บันทึกรหัสข้อความที่ไม่สามารถเปลี่ยนแปลงได้ รหัสงานเชิงตรรกะ ประทับเวลาการเข้าคิว จำนวนการส่งของโบรกเกอร์ จำนวนความพยายามของแอปพลิเคชัน ประเภทข้อผิดพลาด เวอร์ชันของ worker และผลลัพธ์การรับทราบ การจัดการข้อผิดพลาดที่จับข้อยกเว้นแล้วสร้างงานทดแทนขึ้นมาใหม่อาจทำให้เกิดกระแสความพยายามครั้งแรกที่ดูเหมือนจริง การหมดอายุของสัญญาการมองเห็น (visibility lease) อาจทำให้เกิดการส่งซ้ำโดยไม่มีการเข้าคิวใหม่ และการเรดไรฟ (redrive) อาจแนะนำข้อความทางกายภาพชิ้นใหม่ในขณะที่ปฏิบัติการทางธุรกิจเดิมยังคงดำเนินอยู่
ความเหลื่อมล้ำของนาฬิกาเหล่านี้ทำให้เกิดรายงานคุ้นเคยที่ว่าข้อความพิษ (poison message) เพิกเฉยต่อขีดจำกัดสูงสุด คำถามวินิจฉัยแรกจึงดูน่าเบื่อแต่เด็ดขาด นั่นคือ ส่วนประกอบใดเป็นเจ้าของช่วงเปลี่ยนผ่านการลองใหม่ และค่าที่ตรวจสอบนั้นรอดพ้นทุกเส้นทางที่ส่งงานกลับเข้าสู่ระบบบริการหรือไม่ ตรวจสอบเส้นทางความสำเร็จด้วย การรับทราบในเส้นทางทำความสะอาดที่ถูกเลื่อนออกไป สัญญาที่ไม่ได้รอผลลัพธ์ หรือตัวจัดการข้อผิดพลาดกว้าง ๆ ที่แปลงการกระทำทางธุรกิจที่ล้มเหลวให้กลายเป็นความสำเร็จ ล้วนแต่ลบข้อความออกจากคิวในขณะที่ปล่อยให้สถานะที่ตั้งใจไว้หายไป
"A retry loop is an availability problem before it is a queue-setting problem: it can spend all worker slots on work that cannot succeed and raise the age of healthy messages."
Dev.to
การเก็บบันทึกข้อมูลที่คงทนแยกต่างหากสำหรับงานเชิงตรรกะเป็นสิ่งสำคัญ การส่งคิวคือสถานะการขนส่ง ขณะที่ความสำเร็จคือการเขียนฐานข้อมูล การสร้างออบเจ็กต์ หรือสถานะทางธุรกิจอื่น ๆ ที่มองเห็นได้ซึ่งงานถูกสร้างขึ้นมาเพื่อให้บรรลุผล หากคิวรายงานความลึกเป็นศูนย์แต่ไม่มีบันทึกข้อมูลที่คาดหวัง การปรับแต่งการลองใหม่จึงยังไม่ใช่ปัญหาที่แท้จริง ต้องจับคู่รหัสที่ยอมรับแล้วกับผลลัพธ์ที่คงทน และแจ้งเตือนเมื่อเกิดช่องว่างที่คุกคาม SLO ของความสำเร็จ

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
การทำความเข้าใจความแตกต่างระหว่างสถานะของคิว (Transport State) และสถานะทางธุรกิจ (Business State) เป็นหัวใจสำคัญในการแก้ไขปัญหาระบบเบื้องหลัง นักพัฒนาหลายคนมักหลงทางกับการปรับแต่งตัวเลขในคิวโดยไม่ตรวจสอบว่าข้อมูลถูกบันทึกจริงลงในฐานข้อมูลหรือไม่ การแยกส่วนนี้ช่วยป้องกันไม่ให้เกิดความเข้าใจผิดว่างานสำเร็จแล้วเพียงเพราะคิวว่างเปล่า
จัดประเภทความล้มเหลวที่ขอบเขตซึ่งเป็นเจ้าของกระบวนการส่งต่อ การหมดเวลาของการพึ่งพาอาศัยกันชั่วคราวอาจให้เหตุผลสำหรับการลองพยายามอีกครั้ง ข้อมูลนำเข้าที่ไม่ถูกต้อง ฟิลด์ที่จำเป็นที่ขาดหายไป หรือการเปลี่ยนผ่านสถานะที่ไม่รองรับ จำเป็นต้องถูกกักกัน (quarantine) ทันที ความเหนื่อยล้า (exhaustion) ก็ถือเป็นจุดสิ้นสุดเช่นกัน หลังจากถึงขีดจำกัดที่กำหนด worker จะส่งงานไปยัง dead-letter queue แทนที่จะกำหนดเวลาซ้ำ แม้การถอยหลังแบบทวีคูณ (exponential backoff) จะช่วยกระจายความพยายามซ้ำ ๆ ตามเวลา และความล่าช้าแบบสุ่มช่วยลดการระเบิดพร้อมกัน แต่ก็ไม่ได้แทนที่การตัดสินใจเหล่านั้น
โยบายควรจะอธิบายงานเชิงตรรกะที่เสถียร มากกว่าที่จะมองแค่การส่งของโบรกเกอร์เพียงครั้งเดียว รักษาค่าเหล่านี้ไว้ตลอดการลองใหม่และการเรดไรฟ หยุดการเรดไรฟ dead-letter queue โดยอัตโนมัติในระหว่างการตรวจสอบ การกักกันคือหลักฐานไม่ใช่คิวแหล่งที่มาที่สอง เก็บรักษาเพย์โหลด ส่วนหัว ประเภทความล้มเหลว ประทับเวลา ค่าตัวนับ การแก้ไขการปรับใช้ และตัวระบุความสัมพันธ์ไว้ภายใต้กฎการเข้าถึงและการเก็บรักษาที่เหมาะสมกับข้อมูล เพื่อให้สามารถแยกแยะระหว่างเพย์โหลดที่จัดรูปแบบผิดพลาดกับการเปลี่ยนแปลงพฤติกรรมที่เกิดขึ้นจากการปรับใช้ โดยไม่ต้องทำซ้ำทั้งสองอย่าง
ที่มา: Dev.to
พบข้อมูลผิดพลาดในบทความนี้? แจ้งปัญหาบทความนี้
ความคิดเห็น
แสดงความคิดเห็น