Message Center
Multi-channel notification system with template-driven messaging
Background
Centralized message delivery service supporting announcements, notifications, personal messages, and popups across a multi-tenant platform. Must handle high-volume async delivery while tracking read/unread state per user per message.
Architecture
Admin/service → gRPC API (go-zero) → template engine (variable substitution) → Kafka producer → consumer workers → MySQL (5 tables). Announcements cached in Redis for repeated reads.
Key Implementations
Template-Driven Message Rendering
Messages are defined as templates with placeholder variables that are substituted at delivery time with user or event-specific data.
Why: Decouples message content from delivery logic, allowing ops teams to modify copy without code changes or deployments.
Kafka Async Delivery Pipeline
Message send requests are published to Kafka and processed by consumer workers that handle fan-out to target users.
Why: Async ingestion absorbs burst traffic (e.g., system-wide announcements to all users) without blocking the calling service.
Read/Unread Tracking
Maintains per-user read status for each delivered message with efficient queries for unread counts and mark-as-read operations.
Why: Users expect accurate badge counts and the ability to mark messages read; this must scale to millions of delivery records.
Technical Decisions
| Technical Decisions | Chosen | Alternative | Reason |
|---|---|---|---|
| Message delivery | Kafka async | Synchronous gRPC fan-out | Async delivery prevents system-wide announcements from creating O(n) blocking calls proportional to user count. |
| Announcement caching | Redis cache | Database query per request | Announcements are read-heavy and rarely change, making them ideal for caching to reduce database load. |