ข้ามไปยังเนื้อหา
กลับหน้ารายการบทความ

NATS: ข้อความแบบ Pub/Sub ต่างจาก JetStream ที่เก็บและเล่นซ้ำอย่างไร

เทียบ Core NATS กับ JetStream ด้วยเหตุการณ์คำสั่งซื้อ เพื่อเลือก delivery semantics และทดสอบการส่งซ้ำเมื่อ consumer ล้ม

NATS: ข้อความแบบ Pub/Sub ต่างจาก JetStream ที่เก็บและเล่นซ้ำอย่างไร

เมื่อแอปหนึ่งส่งเหตุการณ์ orders.created ให้หลายบริการ NATS ช่วยแยกผู้ส่งออกจากผู้รับ แต่คำว่า “ส่งข้อความแล้ว” ยังไม่บอกว่าผู้รับที่ปิดอยู่จะได้รับภายหลังหรือไม่ บทความนี้ใช้เหตุการณ์คำสั่งซื้อเพื่อแยก Core NATS กับ JetStream และเลือกให้ตรงความสำคัญของข้อมูล

Core NATS ส่งให้ผู้ฟังที่ออนไลน์

ใน Core NATS ผู้ส่ง publish ไปยัง subject เช่น orders.created ผู้รับที่ subscribe อยู่จะได้รับสำเนาตามรูปแบบ pub/sub ผู้ส่งไม่ต้องรู้ชื่อบริการปลายทาง แต่ถ้าผู้รับไม่ได้เชื่อมต่อในเวลานั้น ข้อความจะไม่ถูกเก็บไว้รอ นี่คือ at-most-once delivery เหมาะกับสัญญาณที่พลาดหนึ่งครั้งแล้วระบบยังทำงานต่อได้ เช่น แจ้งสถานะชั่วคราวหรือข้อมูลที่ดึงสถานะปัจจุบันใหม่ได้

ทดสอบง่าย ๆ โดยเปิด subscriber แล้วส่งข้อความหนึ่งครั้ง จากนั้นปิด subscriber ส่งอีกครั้ง และเปิดกลับมา ข้อความช่วงที่ปิดจะไม่ย้อนมาให้เห็น อย่าใช้ผลทดสอบขณะทุกบริการออนไลน์ไปสรุปว่าระบบทนต่อการหยุดทำงานได้

JetStream เพิ่มการเก็บและ consumer

JetStream ผูก stream กับ subject ที่กำหนด เมื่อ publish ตรงเงื่อนไข server จะเก็บข้อความไว้ และ consumer ติดตามตำแหน่งอ่านของตน ผู้รับส่ง acknowledgment เมื่อประมวลผลเสร็จ หากไม่ ack ตามเวลา ระบบอาจส่งอีกครั้ง จึงเป็น at-least-once delivery ไม่ใช่การรับประกันว่าธุรกิจจะทำรายการเพียงครั้งเดียว

สำหรับ orders.created ให้สร้าง stream ที่จับ orders.> แล้วมี consumer สำหรับงานออกใบเสร็จ ทดลองหยุด worker หลังบันทึกใบเสร็จแต่ก่อน ack เมื่อ worker กลับมา ข้อความอาจถูกส่งซ้ำ จึงต้องใช้ order ID เป็นคีย์กันการสร้างใบเสร็จซ้ำ และบันทึกผลก่อน ack อย่างระมัดระวัง

เลือกการตั้งค่าจากผลลัพธ์ที่ต้องการ

ระบุว่าเหตุการณ์ใดหายได้ เหตุการณ์ใดต้องเก็บ และต้องเล่นย้อนหลังนานเท่าไร แล้วกำหนด retention, storage และจำนวนสำเนาให้ตรงกับความเสี่ยง อย่าคิดว่าเปิด JetStream แล้วข้อความอยู่ตลอด เพราะนโยบาย retention และพื้นที่เก็บอาจลบก่อนเวลาที่ธุรกิจคาดไว้ ทดสอบทั้ง consumer offline, server restart และข้อความผิดรูปแบบที่ประมวลผลซ้ำไม่สำเร็จ

ติดตามจำนวนข้อความค้าง การส่งซ้ำ และเวลาจาก publish ถึงประมวลผลเสร็จ หาก backlog เพิ่มต่อเนื่อง ปัญหาอาจอยู่ที่ความเร็ว consumer มากกว่าตัว broker การเลือก Core NATS หรือ JetStream จึงเริ่มจากข้อกำหนดการส่งมอบ ไม่ใช่เปิดโหมดที่ดู “ครบ” ที่สุด

อ่านเพิ่มเติม: NATS Pub/Sub, JetStream