Skip to content

Thực hành: Thiết kế Notification System

🎯 Mục tiêu

🎯 Sau bài thực hành này, bạn sẽ:

  • Thiết kế notification đa kênh (push, email, SMS)
  • Xây dựng priority queue và delivery tracking
  • Giải quyết notification storm và rate limiting per user

Yêu cầu hệ thống

Functional: Gửi push/email/SMS, user chọn kênh, template, tracking, scheduled. Non-functional: 10M/day, OTP trong 5s, at-least-once, dễ thêm kênh mới.

Ước lượng

MetricGiá trị
Notifications/day10M (6M push + 3M email + 1M SMS)
Peak QPS~1,500 (burst)
SMS cost/day~10,000 USD

Kiến trúc

Thiết kế chi tiết

Priority Levels

  • P0 (Critical): OTP, security alerts → gửi ngay, bypass rate limit
  • P1 (Normal): Social notifications → gửi trong 30s
  • P2 (Low): Marketing → giờ thấp điểm, rate limit nghiêm ngặt

Delivery Tracking

State: CREATED → QUEUED → SENT → DELIVERED → READ. Retry tối đa 3 lần, backoff (1s, 4s, 16s).

🎯 Scenario Choice

Xử lý Notification Storm

Flash sale: 5M push + 100K OTP đồng thời. Storm làm chậm OTP delivery.

Giải pháp: (1) Tách queue — OTP → High Queue riêng, (2) Rate limit 5 notif/phút/user cho P1-P2, (3) Batch marketing 1000/batch qua FCM topic, (4) Backpressure tạm dừng P2 khi overload.

💡 Nhiều hệ thống sập vì OTP và marketing dùng chung queue. Tách queue theo priority là nguyên tắc cơ bản.

Trắc nghiệm

🧠 Quiz

Câu 1: Tại sao dùng message queue thay vì gọi API provider trực tiếp?

  • [ ] A) Queue nhanh hơn
  • [x] B) Decouple, retry khi lỗi, absorb spike không mất notification
  • [ ] C) Provider không hỗ trợ gọi trực tiếp
  • [ ] D) Queue chọn provider rẻ nhất

💡 Provider có thể timeout/down. Queue là buffer: lưu an toàn, retry tự động, không overwhelm khi spike.

🧠 Quiz

Câu 2: "At-least-once delivery" nghĩa là gì?

  • [ ] A) Mỗi notification gửi đúng 1 lần
  • [x] B) Có thể gửi trùng nhưng không mất — trùng ít nghiêm trọng hơn mất
  • [ ] C) Gửi ít nhất 2 bản đảm bảo nhận
  • [ ] D) Gửi qua ít nhất 1 kênh

💡 Exactly-once cực khó. At-least-once: không chắc đã gửi → gửi lại. Nhận trùng ít phiền hơn không nhận.

🧠 Quiz

Câu 3: Thiết kế nào giúp thêm kênh mới (Zalo) dễ nhất?

  • [ ] A) Thêm if-else trong worker
  • [ ] B) Worker riêng, hardcode logic
  • [x] C) Channel Adapter — mỗi kênh implement chung interface, đăng ký vào Router
  • [ ] D) Duplicate toàn bộ pipeline

💡 Open/Closed Principle: thêm kênh = implement interface + đăng ký, không sửa code existing.