Messaging and Event-driven Architecture
Messaging services ช่วย decouple systems เพื่อให้ producer และ consumer scale, fail และ deploy แยกกันได้ แต่ต้องออกแบบ retry, DLQ และ idempotency ตั้งแต่ต้น
SQS, SNS และ EventBridge
| Service | Pattern | เหมาะกับ |
|---|---|---|
| SQS | Queue | งาน asynchronous ที่ consumer ดึงไป process เช่น order worker, image processing |
| SNS | Pub/Sub Topic | Fanout message ไปหลาย subscribers เช่น email, Lambda, SQS |
| EventBridge | Event Bus | Routing events จาก SaaS/AWS/custom apps ด้วย rules และ event patterns |
Dead-letter Queue
Dead-letter Queue หรือ DLQ เก็บ messages ที่ process ไม่สำเร็จหลัง retry ครบแล้ว เพื่อให้ทีม debug และ replay อย่างควบคุมได้ DLQ ไม่ใช่ถังขยะ ต้องมี alarm เมื่อมี messages เข้า DLQ
Retry และ visibility timeout
Retry ช่วยให้ transient failures หายเองได้ แต่ถ้า retry ถี่เกินไปจะซ้ำเติม downstream ที่ล่ม สำหรับ SQS ต้องตั้ง visibility timeout ให้ยาวกว่าระยะเวลาประมวลผลปกติ ไม่อย่างนั้น message อาจถูก consumer อื่นรับไปซ้ำก่อนงานเสร็จ
Idempotency
Distributed systems มักมี duplicate delivery หรือ retry จึงต้องออกแบบ consumer ให้ idempotent คือรับ event เดิมซ้ำแล้วไม่สร้างผลลัพธ์ผิด เช่น ไม่ตัดเงินซ้ำ ไม่สร้าง order ซ้ำ หรือไม่ส่ง email ซ้ำโดยไม่ตั้งใจ
Idempotency examples:
- Store processed event IDs in DynamoDB
- Use natural unique keys such as order_id
- Make writes conditional
- Treat repeated request as success when final state already exists
Common mistakes
- ไม่มี DLQ และ alarm ทำให้ messages หายเงียบใน retry loop
- คิดว่า SQS Standard Queue จะส่ง message ครั้งเดียวเสมอ ทั้งที่ต้องรับมือ at-least-once delivery
- ส่งข้อมูล sensitive ข้าม account/environment ผ่าน events โดยไม่มี data classification
Review questions
- Queue ต่างจาก Pub/Sub อย่างไร?
- DLQ ควรมี alarm เพราะอะไร?
- Idempotency สำคัญกับ retry อย่างไร?