อะไรคือสาเหตุที่ทำให้ข้อความถูกย้ายไปยังคิวข้อความที่ส่งไม่ถึงผู้รับ?
โดยทั่วไป ข้อความจะเข้าสู่คิวข้อความที่ส่งไม่สำเร็จ (DLQ) หลังจากใช้จำนวนครั้งที่กำหนดในการลองส่งซ้ำจนหมด ซึ่งอาจหมายถึงการเกินจำนวนการรับสูงสุดใน SQS การส่งล้มเหลวไปยังผู้รับหลายราย หรือถูกปฏิเสธโดยโค้ดแอปพลิเคชันโดยตรง ตัวกระตุ้นที่แน่นอนจะแตกต่างกันไปตามแพลตฟอร์ม AWS SQS ใช้การกำหนดนโยบายการส่งซ้ำที่ระบุจำนวนการรับสูงสุด ในขณะที่ Azure Service Bus ติดตามจำนวนการส่ง เมื่อถึงเกณฑ์ดังกล่าว โครงสร้างพื้นฐานการส่งข้อความจะย้ายหรือคัดลอกข้อความไปยังคิวข้อความที่ส่งไม่สำเร็จที่เกี่ยวข้องโดยอัตโนมัติ
การลองใหม่ในหน่วยความจำจัดการกับการเริ่มต้นกระบวนการใหม่หรือข้อผิดพลาดอย่างไร?
แต่ระบบเหล่านั้นทำไม่ได้ ซึ่งเป็นข้อจำกัดพื้นฐานของมัน สถานะการลองใหม่ใดๆ จะมีอยู่เฉพาะในหน่วยความจำของกระบวนการที่กำลังทำงานอยู่เท่านั้น หากแอปพลิเคชันล่ม ถูกปิดระหว่างการปรับใช้ หรือคอนเทนเนอร์ถูกกำหนดเวลาใหม่ การลองใหม่ที่ค้างอยู่ทั้งหมดและบริบทของมันจะหายไป สำหรับการดำเนินการที่ต้องคงอยู่แม้เหตุการณ์ดังกล่าว คุณจำเป็นต้องมีกลไกการลองใหม่แบบถาวร ไม่ว่าจะเป็น DLQ คิวงานที่ใช้ฐานข้อมูล หรือระบบงานแบบกระจาย เช่น Celery หรือ Hangfire
คุณสามารถรวมคิวข้อความที่ส่งไม่สำเร็จ (dead letter queue) กับการลองส่งซ้ำในหน่วยความจำ (in-memory retries) ในระบบเดียวกันได้หรือไม่?
แน่นอน และนี่เป็นแนวทางปฏิบัติที่ดีที่สุดสำหรับหลายทีมด้วยซ้ำ รูปแบบทั่วไปคือการลองใหม่ในหน่วยความจำโดยใช้การหน่วงเวลาแบบทวีคูณสำหรับการกู้คืนชั่วคราวในทันที เช่น การลองสามครั้งในช่วงเวลาไม่กี่วินาที หากการลองเหล่านั้นล้มเหลว ข้อความหรือการดำเนินการจะถูกส่งไปยังคิวที่มีการสนับสนุน DLQ สำหรับการจัดการที่ทนทาน ซึ่งจะให้ความเร็วในการลองใหม่ในหน่วยความจำสำหรับปัญหาเล็กน้อย และความปลอดภัยของ DLQ สำหรับปัญหาที่เกิดขึ้นอย่างต่อเนื่อง
ควรตั้งค่าการตรวจสอบอย่างไรสำหรับคิวจดหมายที่ส่งไม่ถึงผู้รับ?
อย่างน้อยที่สุด ควรตั้งค่าการแจ้งเตือนเกี่ยวกับความลึกของคิว อายุของข้อความที่เก่าที่สุด และอัตราการรับข้อความ การเพิ่มขึ้นอย่างกะทันหันของการรับข้อความใน DLQ มักบ่งชี้ถึงข้อผิดพลาดในการใช้งาน การแจ้งเตือนเกี่ยวกับอายุของข้อความจะช่วยตรวจจับกรณีที่การเล่นซ้ำไม่เกิดขึ้น ทีมหลายทีมยังติดตามอัตราส่วนของข้อความใน DLQ ต่อข้อความที่ประมวลผลสำเร็จเพื่อเป็นตัวบ่งชี้สถานะการทำงาน CloudWatch, Azure Monitor หรือ Datadog สามารถแสดงเมตริกเหล่านี้ได้ด้วยการผสานรวมเพจเจอร์
มีทางเลือกอื่นนอกเหนือจาก DLQ และการลองใหม่ในหน่วยความจำหรือไม่?
รูปแบบต่างๆ มากมายตอบสนองความต้องการที่คล้ายคลึงกัน รูปแบบ Outbox จะจัดเก็บเหตุการณ์แบบธุรกรรมพร้อมกับข้อมูลทางธุรกิจ ทำให้มั่นใจได้ถึงความเป็นอะตอมิก รูปแบบ Saga จัดการธุรกรรมแบบกระจายที่ใช้เวลานานด้วยการดำเนินการชดเชย คิวงานที่ใช้ฐานข้อมูล เช่น Sidekiq หรือ pg-boss ให้การคงอยู่ของข้อมูลโดยไม่ต้องใช้ตัวกลางส่งข้อความโดยเฉพาะ Event sourcing สร้างสถานะขึ้นใหม่จากบันทึกแบบเพิ่มอย่างเดียว ทำให้ความหมายของการลองใหม่แตกต่างออกไป การเลือกที่เหมาะสมขึ้นอยู่กับข้อกำหนดด้านความสม่ำเสมอและโครงสร้างพื้นฐานที่มีอยู่ของคุณ
คุณจะเล่นข้อความจากคิวข้อความที่ส่งไม่ถึงผู้รับได้อย่างปลอดภัยได้อย่างไร?
ห้ามเล่นซ้ำกลับไปยังคิวเดิมโดยตรงโดยไม่ตรวจสอบก่อน เพราะนั่นจะทำให้เกิดลูปไม่สิ้นสุดหากสาเหตุหลักยังคงอยู่ ควรดึงข้อความจาก DLQ ไปยังสภาพแวดล้อมการวิเคราะห์แยกต่างหาก ตรวจสอบตัวอย่างที่แสดงถึงรูปแบบความล้มเหลว แก้ไขปัญหาที่ต้นเหตุ จากนั้นจึงเล่นซ้ำเป็นชุดๆ อย่างเลือกสรรพร้อมกับการตรวจสอบ AWS มีฟีเจอร์การเล่นซ้ำ DLQ และเครื่องมืออย่าง Amazon EventBridge Pipes สามารถช่วยให้เวิร์กโฟลว์การเล่นซ้ำแบบมีเงื่อนไขเป็นไปโดยอัตโนมัติได้
อะไรคือคุณสมบัติของนโยบายการลองใหม่ที่ดีสำหรับการลองใหม่ในหน่วยความจำ?
การหน่วงเวลาแบบทวีคูณพร้อมค่าความคลาดเคลื่อน (jitter) ถือเป็นมาตรฐานที่ดีที่สุด หากไม่มีค่าความคลาดเคลื่อน การลองใหม่พร้อมกันจากไคลเอนต์หลายรายอาจก่อให้เกิดปัญหาการรุมเร้าอย่างรุนแรงต่อบริการที่กำลังกู้คืน ควรจำกัดเวลาหน่วงสูงสุดเพื่อป้องกันการรอคอยที่ไม่มีขอบเขต และควรกำหนดจำนวนครั้งการลองใหม่สูงสุดเสมอ ควรพิจารณาใช้ตัวตัดวงจร (circuit breakers) ที่หยุดการลองใหม่ทั้งหมดเมื่ออัตราความล้มเหลวเกินเกณฑ์ที่กำหนด เพื่อให้บริการปลายทางมีเวลาในการกู้คืนแทนที่จะถูกโจมตีอย่างหนักในขณะที่บริการเหล่านั้นกำลังล่ม
ฟังก์ชันแบบ Serverless ทำงานได้ดีกับการลองใหม่ในหน่วยความจำหรือไม่?
ไม่เชิงครับ ฟังก์ชัน Lambda และฟังก์ชันที่คล้ายกันถูกออกแบบมาให้ไม่มีสถานะและมีอายุสั้น เวลาการทำงานสูงสุดสิบห้านาทีหมายความว่าหน้าต่างการลองใหม่ในหน่วยความจำของคุณมีจำกัด ที่สำคัญกว่านั้น หาก Lambda ล้มเหลว บริบทการทำงานทั้งหมดจะหายไป สถาปัตยกรรมแบบ Serverless สนับสนุนสถานะภายนอกอย่างมาก ทำให้ DLQ หรือฟังก์ชันขั้นตอนที่มีตรรกะการลองใหม่ในตัวเหมาะสมกว่าวิธีการในหน่วยความจำมาก
วิธีการทั้งสองนี้มีข้อกังวลเรื่องการจัดลำดับข้อความที่แตกต่างกันอย่างไร?
DLQ อาจทำให้การรับประกันลำดับซับซ้อนขึ้น หากคิวหลักของคุณเป็นแบบ FIFO การย้ายข้อความเข้าและออกจาก DLQ อาจทำให้ลำดับผิดเพี้ยนไปได้ เว้นแต่แพลตฟอร์มจะรักษาลำดับไว้โดยเฉพาะ การลองใหม่ในหน่วยความจำภายในผู้บริโภครายเดียวจะรักษาลำดับของข้อความของผู้บริโภครายนั้นไว้โดยธรรมชาติ แม้ว่าจะมีผู้บริโภคหลายรายประมวลผลพร้อมกันก็ตาม บางระบบใช้หมายเลขลำดับหรือการจัดลำดับระดับแอปพลิเคชันเพื่อสร้างลำดับที่ถูกต้องขึ้นใหม่หลังจากกลไกการลองใหม่ใดๆ
ข้อควรพิจารณาด้านความปลอดภัยใดบ้างที่เกี่ยวข้องกับคิวจดหมายที่ส่งไม่ถึงผู้รับ?
DLQ (Delayed Licensing Queue) มีข้อมูลสำคัญเช่นเดียวกับคิวหลักของคุณ บางครั้งอาจมีมากกว่าด้วยซ้ำ เนื่องจากมีบริบทของความล้มเหลวรวมอยู่ด้วย ควรใช้การเข้ารหัส การควบคุมการเข้าถึง และการบันทึกการตรวจสอบที่เหมือนกันทุกประการ ควรระมัดระวังเกี่ยวกับกลไกการเล่นซ้ำ การประมวลผลข้อความเก่าซ้ำอาจทำให้เกิดผลข้างเคียงที่ไม่คาดคิดหากระบบปลายทางไม่สามารถทำงานซ้ำได้โดยอัตโนมัติ อุตสาหกรรมบางประเภทที่อยู่ภายใต้การกำกับดูแลกำหนดให้ต้องมีขั้นตอนการอนุมัติที่ชัดเจนก่อนที่จะสามารถเข้าถึงหรือเล่นซ้ำข้อความใน DLQ ได้
เมื่อใดที่คุณควรหลีกเลี่ยงการลองใหม่ในหน่วยความจำโดยสิ้นเชิง?
ควรหลีกเลี่ยงการใช้ฟังก์ชันนี้เมื่อการประมวลผลมีผลข้างเคียงที่ไม่สามารถทำซ้ำได้ เช่น การเรียกเก็บเงินจากบัตรเครดิตสองครั้งเนื่องจากการลองใหม่ ซึ่งเป็นเรื่องร้ายแรง ควรหลีกเลี่ยงการใช้ฟังก์ชันนี้เมื่อความหมายแบบ "ดำเนินการเพียงครั้งเดียว" มีความสำคัญและคุณขาดการกำจัดข้อมูลซ้ำซ้อน อย่าพึ่งพาฟังก์ชันนี้สำหรับการดำเนินการที่ใช้เวลานานซึ่งกระบวนการอาจมีอายุไม่เพียงพอที่จะทำการลองใหม่ให้เสร็จสมบูรณ์ และอย่าใช้ฟังก์ชันนี้เมื่อทีมปฏิบัติการต้องการตรวจสอบรูปแบบความล้มเหลวโดยไม่ต้องปรับใช้การเปลี่ยนแปลงโค้ด
ต้นทุนในระดับองค์กรแตกต่างกันอย่างไร?
โดยทั่วไปแล้ว การตั้งค่า AWS ด้วยคิวมาตรฐาน SQS และ DLQ อาจมีค่าใช้จ่ายไม่กี่ดอลลาร์ต่อข้อความล้านข้อความ บวกกับพื้นที่จัดเก็บสำหรับข้อความที่เก็บไว้ สำหรับระบบที่ประมวลผลหลายพันล้านข้อความต่อเดือน ค่าใช้จ่ายนี้จะมีความสำคัญมาก การลองส่งซ้ำในหน่วยความจำจะเปลี่ยนค่าใช้จ่ายไปที่การประมวลผล ซึ่งคุณจ่ายอยู่แล้ว อย่างไรก็ตาม การลองส่งซ้ำจำนวนมากอาจทำให้ CPU และหน่วยความจำทำงานผิดปกติ ซึ่งอาจต้องใช้ขนาดอินสแตนซ์ที่ใหญ่ขึ้น การวิเคราะห์ต้นทุนรวมส่วนใหญ่สนับสนุนการใช้หน่วยความจำสำหรับงานที่มีความสำคัญต่ำและปริมาณมาก และใช้ DLQ สำหรับเวิร์กโฟลว์ที่สำคัญแต่ปริมาณน้อย