A containerized real-time message queue pipeline built with Python, Kafka, Redis, Rust, and gRPC.
Python Producer -> Kafka topic: log-events -> Rust Kafka Consumer
\
-> Kafka topic: log-events-dlq (on parse/processing failures)
- Consumer uses explicit offset commits (
enable.auto.commit=false). - Offsets are committed only after successful processing or after DLQ handoff.
- Poison or malformed records are sent to DLQ (
log-events-dlq). - Rust Kafka Consumer and Rust gRPC service implement distributed idempotency by
log_idusing Redis (SETNXwith TTL).
- Python:
kafka-python - Rust:
tonic,tokio,prost,rdkafka,redis-rs - Backing Stores:
wurstmeister/kafka,wurstmeister/zookeeper,redis:7-alpine - Container orchestration: Docker Compose
Canonical protobuf is defined in proto/logs.proto.
LogMessage fields:
log_idcontenttimestamplevelschema_version
- Build and start:
docker-compose up --build
- Follow service logs:
docker-compose logs -f producer rust_kafka_consumer rust-grpc
- Stop stack:
docker-compose down
- Kafka health: port
9092. - Rust gRPC health: port
50051. - Redis health: port
6379. - Compose uses health-based
depends_onfor startup ordering.
- Confirm service status:
docker-compose ps
- Inspect consumer logic:
docker-compose logs -f rust_kafka_consumer
- Invalid JSON or malformed payload: consumer sends record to DLQ and commits.
- Duplicate
log_id: Rust service returnsduplicate_ignoredor logs ignored event, and consumer commits.
To test the End-to-End (E2E) flow in a production-like environment:
Start the environment in the background:
docker-compose up --build -d
Follow the logs to verify E2E flow:
docker-compose logs -f producer rust_kafka_consumer rust-grpc
Expected Results:
- The producer is configured to send 30 messages.
- You should see
message_producedlogs from the producer. - You should see exactly 30
log_processedlogs from the Rust Kafka Consumer.
Tear down and Clean up: To stop the stack, remove containers, and delete the associated volumes and images:
docker-compose down -v --rmi all
If you want to forcefully prune all unused dangling images on your system:
docker image prune -f
python3 -m pip install -r producer/requirements.txt pytest
python3 -m pytest producer/test_producer.pycargo test --workspacedocker-compose configThe CI workflow runs:
- Python unit tests
- Rust tests
- Docker Compose config validation