The Dead Letter Queue (DLQ) system ensures that failed Kafka messages are not lost and can be reprocessed. This implementation provides comprehensive DLQ management including monitoring, alerting, and reprocessing capabilities.
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Main Topic │───▶│ Consumer │───▶│ Processing │
│ (e.g., │ │ (Retry 3x) │ │ (Success) │
│ booking- │ │ │ │ │
│ created) │ └─────────────────┘ └─────────────────┘
└─────────────────┘ │
│ (After 3 retries)
▼
┌─────────────────┐
│ DLQ Topic │
│ (booking- │
│ created.DLT) │
└─────────────────┘
│
▼
┌─────────────────┐
│ DLQ Management │
│ - Monitoring │
│ - Alerting │
│ - Reprocessing │
└─────────────────┘
- Failed messages are automatically routed to
<topic>.DLT(Dead Letter Topic) - Retry logic: 3 retries with 1-second delay before routing to DLQ
- Non-retryable exceptions (IllegalArgumentException, NullPointerException) skip retries
- Real-time DLQ statistics (message count, partition count)
- Prometheus metrics integration
- REST API for querying DLQ status
- Automatic monitoring every 5 minutes
- Alerts when DLQ exceeds threshold (default: 10 messages)
- Cooldown period to prevent alert spam (1 hour)
- Manual reprocessing of DLQ messages back to main topic
- Message inspection without consumption
- Batch reprocessing with configurable limits
spring:
kafka:
bootstrap-servers: localhost:9092
consumer:
group-id: notification-service
auto-offset-reset: earliest
enable-auto-commit: false
producer:
acks: all
retries: 3
# DLQ Configuration
dlq:
alerting:
enabled: true
threshold: 10 # Alert if DLQ has more than 10 messages
check-interval: 300000 # Check every 5 minutes@Bean
public CommonErrorHandler errorHandler(KafkaTemplate<String, Object> kafkaTemplate) {
DeadLetterPublishingRecoverer recoverer = new DeadLetterPublishingRecoverer(
kafkaTemplate,
(record, ex) -> {
String dltTopic = record.topic() + ".DLT";
return new TopicPartition(dltTopic, record.partition());
}
);
DefaultErrorHandler handler = new DefaultErrorHandler(
recoverer,
new FixedBackOff(1000L, 3) // 1 second delay, 3 retries
);
handler.addNotRetryableExceptions(
IllegalArgumentException.class,
NullPointerException.class
);
return handler;
}GET /api/dlq/stats/{dltTopic}Response:
{
"topic": "booking-created.DLT",
"messageCount": 5,
"partitionCount": 1,
"timestamp": "2025-11-09T18:30:00",
"error": null
}GET /api/dlq/statsResponse:
{
"booking-created.DLT": {
"topic": "booking-created.DLT",
"messageCount": 5,
"partitionCount": 1
},
"payment-initiated.DLT": {
"topic": "payment-initiated.DLT",
"messageCount": 2,
"partitionCount": 1
}
}POST /api/dlq/reprocess
Content-Type: application/json
{
"dltTopic": "booking-created.DLT",
"mainTopic": "booking-created",
"maxRecords": 10
}Response:
{
"dltTopic": "booking-created.DLT",
"mainTopic": "booking-created",
"reprocessedCount": 8,
"failedCount": 2,
"startTime": "2025-11-09T18:30:00",
"endTime": "2025-11-09T18:30:05",
"error": null
}GET /api/dlq/inspect/{dltTopic}?maxMessages=10Response:
[
{
"topic": "booking-created.DLT",
"partition": 0,
"offset": 123,
"key": "PNR123456",
"timestamp": "2025-11-09T18:25:00",
"valueString": "{\"bookingId\":123,\"userId\":1,...}"
}
]The DLQ system exposes the following metrics:
kafka.dlq.messages.total- Total messages sent to DLQkafka.dlq.reprocessed.total- Total messages reprocessed from DLQkafka.dlq.reprocess.failed.total- Total failed reprocessing attemptskafka.dlq.messages.count{topic="..."}- Current message count in DLQ per topic
- Scheduled task runs every 5 minutes
- Checks all DLQ topics for threshold violations
- Logs warnings when threshold exceeded
- Respects cooldown period (1 hour between alerts)
- Default threshold: 10 messages
- Configurable via
dlq.alerting.threshold - Can be disabled via
dlq.alerting.enabled=false
The alerting system can be extended to integrate with:
- Email notifications
- Slack webhooks
- PagerDuty alerts
- Prometheus AlertManager
curl http://localhost:8095/api/dlq/stats/booking-created.DLTcurl -X POST http://localhost:8095/api/dlq/reprocess \
-H "Content-Type: application/json" \
-d '{
"dltTopic": "booking-created.DLT",
"mainTopic": "booking-created",
"maxRecords": 10
}'curl http://localhost:8095/api/dlq/inspect/booking-created.DLT?maxMessages=5-
Monitor DLQ Regularly
- Set up alerts for DLQ threshold violations
- Review DLQ messages weekly
- Investigate root causes of failures
-
Reprocess with Caution
- Fix the root cause before reprocessing
- Reprocess in small batches
- Monitor reprocessing results
-
DLQ Retention
- Configure Kafka retention policies for DLQ topics
- Archive old DLQ messages for analysis
- Don't let DLQ grow indefinitely
-
Error Handling
- Log detailed error information
- Include correlation IDs for tracing
- Document common failure patterns
- Check consumer logs for error patterns
- Verify external service dependencies
- Review retry configuration
- Check for serialization issues
- Verify main topic exists and is accessible
- Check message format compatibility
- Review consumer group configuration
- Check Kafka connectivity
- Verify
dlq.alerting.enabled=true - Check alert threshold configuration
- Review application logs for alert messages
- Verify scheduling is enabled
-
Automatic Reprocessing
- Scheduled reprocessing of DLQ messages
- Exponential backoff for failed reprocessing
- Success rate monitoring
-
DLQ Analytics
- Failure pattern analysis
- Root cause identification
- Trend visualization
-
Advanced Alerting
- Integration with external alerting systems
- Custom alert rules
- Alert escalation policies
-
DLQ Dashboard
- Real-time DLQ visualization
- Historical trends
- Interactive reprocessing UI
DlqManagementService.java- DLQ management operationsDlqManagementController.java- REST API for DLQ managementDlqAlertingService.java- DLQ monitoring and alertingSchedulingConfig.java- Scheduling configurationDEAD_LETTER_QUEUE_IMPLEMENTATION.md- This documentation
KafkaConfig.java- Enhanced error handler with retry logicapplication.yml- Added DLQ configuration
# 1. Create a booking that will fail processing
# 2. Check DLQ statistics
curl http://localhost:8095/api/dlq/stats/booking-created.DLT
# 3. Inspect failed messages
curl http://localhost:8095/api/dlq/inspect/booking-created.DLT
# 4. Reprocess messages
curl -X POST http://localhost:8095/api/dlq/reprocess \
-H "Content-Type: application/json" \
-d '{"dltTopic":"booking-created.DLT","mainTopic":"booking-created","maxRecords":5}'The DLQ implementation provides a robust solution for handling failed Kafka messages, ensuring no messages are lost and providing tools for monitoring, alerting, and reprocessing. This significantly improves the reliability and observability of the event-driven architecture.