Skip to content

king-407/distributed-notification-system

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

7 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ Distributed Notification System

A fault-tolerant event-driven notification platform built using Spring Boot microservices, Apache Kafka, Redis, and MySQL.

This project demonstrates how modern distributed backend systems achieve:

  • asynchronous communication,
  • reliable event publishing,
  • retry handling,
  • idempotency,
  • eventual consistency,
  • DLQ processing,
  • and resilient microservice communication.

✨ Features

βœ… Event-Driven Architecture

Microservices communicate asynchronously through Apache Kafka.

βœ… Transactional Outbox Pattern

Prevents dual-write inconsistencies between database transactions and Kafka publishing.

βœ… Eventual Consistency

Distributed services independently process events while eventually reaching consistent business state.

βœ… Redis-based Idempotency

Prevents duplicate notification creation during retries or repeated client requests.

βœ… Redis Fixed-Window Rate Limiting

Protects APIs from abuse and excessive request bursts.

βœ… Retry Mechanisms

  • Kafka publishing retries
  • Email delivery retries
  • Exponential backoff support

βœ… Dead Letter Queue (DLQ)

Unrecoverable failures are routed to dedicated Kafka DLQ topics for debugging and replay.

βœ… Failure Recovery

Handles:

  • Kafka downtime
  • Duplicate Kafka events
  • SMTP failures
  • Service crashes
  • Retry exhaustion
  • Temporary infrastructure failures

πŸ—οΈ High-Level Architecture

                           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                           β”‚     Client/API      β”‚
                           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                      β”‚
                                      β–Ό
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚      notification-service      β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚                 β”‚
                         β”‚                 β”‚
                         β–Ό                 β–Ό
               notifications         outbox_events
                    (MySQL)             (MySQL)
                                              β”‚
                                              β–Ό
                                   Outbox Scheduler
                                              β”‚
                                              β–Ό
                         Kafka Topic: notification-events-topic
                                              β”‚
                                              β–Ό
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚          email-service         β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚                 β”‚
                         β”‚                 β”‚
                         β–Ό                 β–Ό
                   sent_emails        outbox_events
                      (MySQL)             (MySQL)
                         β”‚
                         β–Ό
                  Email Retry Scheduler
                         β”‚
                         β–Ό
                  SMTP / Email Sender
                         β”‚
                         β–Ό
               notification-status-topic
                         β”‚
                         β–Ό
                    notification-service
                         β”‚
                         β–Ό
               notifications.status updated

🧠 System Design Highlights

πŸ”Ή Transactional Outbox Pattern

Instead of directly publishing Kafka events after DB writes, events are first persisted inside an outbox_events table.

A scheduler later publishes those events reliably to Kafka.

This guarantees:

  • no event loss,
  • retry capability,
  • eventual consistency,
  • safe recovery from Kafka downtime.

πŸ”Ή Dual Retry Architecture

The system separately retries:

1. Email Delivery Retry

Retries actual SMTP/email delivery failures.

Stored in:

sent_emails.retryCount

2. Kafka Publish Retry

Retries failed Kafka publishing of outbox events.

Stored in:

outbox_events.retryCount

This separation models real production-grade distributed systems.


πŸ”Ή Idempotency Handling

Duplicate API requests are prevented using Redis idempotency keys.

Idempotency-Key: abc-123

Repeated requests with same key:

  • do not create duplicate notifications,
  • do not create duplicate Kafka events.

πŸ”Ή Dead Letter Queue (DLQ)

Permanent failures are routed to:

email-dlq-topic

Used for:

  • debugging,
  • replay,
  • operational monitoring.

🧩 Microservices


1️⃣ notification-service

Responsible for:

  • receiving notification requests,
  • saving notification records,
  • handling idempotency,
  • rate limiting,
  • publishing Kafka notification events,
  • consuming final email status updates.

Key Components

Component Responsibility
NotificationController REST API layer
NotificationService Core business logic
IdempotencyService Redis-based duplicate protection
RateLimiterService Redis fixed-window rate limiting
OutboxScheduler Reliable Kafka publishing
NotificationStatusConsumer Consumes EMAIL_SENT / EMAIL_FAILED

2️⃣ email-service

Responsible for:

  • consuming notification events,
  • sending emails asynchronously,
  • retrying failed email deliveries,
  • publishing final email delivery status,
  • DLQ handling.

Key Components

Component Responsibility
EmailNotificationConsumer Kafka consumer
EmailService Core email processing logic
EmailSenderService SMTP/email sending
EmailRetryScheduler Retries failed email sends
OutboxScheduler Reliable Kafka publishing
DlqService Handles unrecoverable failures

πŸ“¦ Kafka Topics

Topic Purpose
notification-events-topic Notification creation events
notification-status-topic Final email delivery status
email-dlq-topic Failed unrecoverable events

πŸ—„οΈ Database Design

notification_db

notifications

Tracks business notification lifecycle.

Status
PENDING
SENT
FAILED

outbox_events

Tracks reliable Kafka event publishing.

Status
PENDING
FAILED
PUBLISHED
DEAD_LETTERED

email_db

sent_emails

Tracks actual email delivery lifecycle.

Status
PROCESSING
RETRY_PENDING
SENT
FAILED

outbox_events

Tracks reliable Kafka status event publishing.


πŸ” End-to-End Success Flow

Client Request
β†’ notification-service
β†’ Save Notification
β†’ Save Outbox Event
β†’ Kafka Publish
β†’ email-service Consumes Event
β†’ Email Sent Successfully
β†’ Save EMAIL_SENT Outbox Event
β†’ Kafka Publish
β†’ notification-service Consumes EMAIL_SENT
β†’ Notification marked SENT

❌ Failure Flow Example

Client Request
β†’ Kafka Publish Success
β†’ email-service Consumes Event
β†’ SMTP Failure
β†’ Retry Scheduled
β†’ Retries Exhausted
β†’ EMAIL_FAILED Outbox Event Created
β†’ Kafka Publish
β†’ notification-service Consumes EMAIL_FAILED
β†’ Notification marked FAILED
β†’ Failure Routed to DLQ

βš™οΈ Tech Stack

Technology Usage
Java 21 Backend Language
Spring Boot Microservices Framework
Spring Kafka Kafka Integration
Spring Data JPA ORM Layer
Apache Kafka Event Streaming
Redis Idempotency + Rate Limiting
MySQL Persistent Storage
Docker Compose Local Infrastructure
Lombok Boilerplate Reduction
Maven Dependency Management

πŸ“‚ Project Structure

distributed-notification/
β”‚
β”œβ”€β”€ common-events/
β”‚
β”œβ”€β”€ notification-service/
β”‚
β”œβ”€β”€ email-service/
β”‚
β”œβ”€β”€ docker-compose.yml
β”‚
└── mysql-init/

πŸš€ Running the Project

1️⃣ Start Infrastructure

docker compose up -d

2️⃣ Start notification-service

cd notification-service
mvn spring-boot:run

3️⃣ Start email-service

cd email-service
mvn spring-boot:run

πŸ§ͺ API Testing

Create Notification

Endpoint

POST /api/v1/notifications

Headers

Idempotency-Key: abc-123

Request Body

{
  "recipient": "shivam@gmail.com",
  "subject": "Welcome",
  "message": "Welcome to NotifyX"
}

πŸ” Failure Scenarios Tested

  • βœ… Kafka broker downtime
  • βœ… Duplicate API requests
  • βœ… Duplicate Kafka delivery
  • βœ… Email service downtime
  • βœ… Kafka publish failures
  • βœ… SMTP failures
  • βœ… Retry exhaustion
  • βœ… Scheduler recovery
  • βœ… DLQ routing
  • βœ… Eventual consistency recovery

πŸ“ˆ Future Improvements

  • Kubernetes Deployment
  • API Gateway
  • Authentication & Authorization
  • Prometheus + Grafana Monitoring
  • Distributed Tracing
  • OpenTelemetry
  • Email Templates
  • Multi-channel Notifications (SMS/Push)
  • Circuit Breakers
  • Saga Pattern

πŸ‘¨β€πŸ’» Author

Shivam Tiwari

Backend Engineer passionate about distributed systems, scalable backend architectures, and event-driven microservices.


About

An application for handling notifications in a distributed system.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages