A production-ready, microservices-based distributed ticketing system built with Spring Boot, implementing event-driven architecture and the Saga pattern for distributed transaction management. This system provides a scalable, resilient solution for managing ticket booking operations across multiple services with comprehensive monitoring and observability.
The Ticketing System is designed to handle the complete lifecycle of ticket booking operations, from user registration and authentication to inventory management, payment processing, and notifications. The system employs modern architectural patterns including microservices, event-driven communication, CQRS, and distributed transaction orchestration to ensure consistency, reliability, and scalability.
Key architectural decisions focus on loose coupling between services, eventual consistency, and fault tolerance. Services communicate asynchronously through Kafka, ensuring high throughput and resilience to individual service failures.
The following diagram illustrates the high-level architecture of the ticketing system:
The architecture follows an event-driven microservices pattern with the following key components:
- Client Layer: External clients accessing the system
- NGINX Edge Layer: Load balancer and reverse proxy at the edge
- API Gateway: Spring Cloud Gateway routing requests to appropriate services
- Microservices: Independent services (User, Ticket, Payment, Inventory, Notification, Saga Orchestrator)
- Kafka Event Backbone: Central message broker for asynchronous event-driven communication
- Service Discovery: Consul for service registration and discovery
- Data Stores: MySQL for persistent storage, Redis for caching and distributed locking
- Elastic: Event processing for logging and analytics
- Microservices Architecture: Independent, scalable services with clear domain boundaries
- Event-Driven Communication: Asynchronous messaging via Apache Kafka for decoupled service interaction
- Saga Pattern: Distributed transaction orchestration with automatic compensation on failures
- CQRS Implementation: Command Query Responsibility Segregation in Ticket Service for optimized read/write operations
- Service Discovery: Consul-based service registration and discovery
- API Gateway: Single entry point with routing, load balancing, and circuit breaking
- Resilience Patterns: Circuit breakers, retries, and distributed locking for fault tolerance
- Caching: Redis-based caching and distributed locking for performance optimization
- Monitoring & Observability: Prometheus metrics collection and Grafana dashboards
- Search & Analytics: Elasticsearch integration for advanced search capabilities
- Health Checks: Comprehensive health endpoints for all services
- API Documentation: OpenAPI/Swagger documentation for all services
- Containerization: Docker and Docker Compose for easy deployment
- Kubernetes Support: Kubernetes manifests for production deployment
- Java 21: Modern Java features and performance improvements
- Spring Boot 3.2.0: Application framework and runtime
- Spring Cloud 2023.0.0: Microservices patterns and integrations
- Maven: Build and dependency management
- Spring Cloud Gateway: Reactive API gateway
- Apache Kafka: Event streaming and messaging
- Spring Kafka: Kafka integration for event-driven communication
- MySQL 8.0: Primary relational database
- Spring Data JPA: Data persistence layer
- Redis 7: Caching and distributed locking
- Elasticsearch 8.11.0: Search and analytics engine
- Consul: Service discovery and configuration management
- Resilience4j: Circuit breaker, retry, and rate limiting
- Spring Actuator: Application monitoring and management
- Micrometer: Metrics abstraction
- Prometheus: Metrics collection and storage
- Grafana: Metrics visualization and dashboards
- Docker: Containerization
- Docker Compose: Multi-container orchestration
- Nginx: Load balancer and reverse proxy
- Kubernetes: Container orchestration (optional)
- SpringDoc OpenAPI: API documentation generation
- Swagger UI: Interactive API documentation
ticketing-system/
├── api-gateway/ # API Gateway service (Spring Cloud Gateway)
├── ticket-service/ # Ticket management service (CQRS pattern)
├── user-service/ # User management service
├── payment-service/ # Payment processing service
├── notification-service/ # Notification service
├── inventory-service/ # Inventory and seat reservation service
├── saga-orchestrator-service/ # Saga orchestration service
├── common-event-library/ # Shared event models and DTOs
├── k8s/ # Kubernetes deployment manifests
│ ├── deployments/ # Service deployments
│ ├── services/ # Service definitions
│ ├── ingress/ # Ingress configurations
│ └── autoscaling/ # HPA configurations
├── nginx/ # Nginx configuration
├── grafana/ # Grafana provisioning
├── docker-compose.yml # Docker Compose configuration
├── prometheus.yml # Prometheus configuration
└── init-db.sql # Database initialization script
- Java 21 or higher
- Maven 3.6+
- Docker and Docker Compose
- Git
-
Clone the repository:
git clone https://github.com/serhatsoysal/event-driven-ticketing-platform.git cd ticketing-system -
Configure environment variables:
# Copy the example environment file cp .env.example .env # Generate a secure JWT secret # For Windows PowerShell: $bytes = New-Object byte[] 64 [Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($bytes) [Convert]::ToBase64String($bytes) # For Linux/Mac: openssl rand -base64 64 # Edit .env and replace JWT_SECRET with the generated value # Also update other credentials as needed
Security Note: Never commit the
.envfile to version control. Always generate your own secure JWT secret using cryptographically secure random generators (minimum 512 bits). -
Build the project:
mvn clean install
-
Start infrastructure services:
docker-compose up -d consul mysql kafka redis elasticsearch prometheus grafana kibana zookeeper
-
Wait for services to be healthy:
docker-compose ps docker-compose logs -f
-
Start application services:
docker-compose up -d
The application requires environment variables to be configured before running. A template file .env.example is provided in the repository.
-
Copy the template:
cp .env.example .env
-
Generate a secure JWT secret:
For Windows (PowerShell):
$bytes = New-Object byte[] 64 [Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($bytes) [Convert]::ToBase64String($bytes)
For Linux/Mac:
openssl rand -base64 64
-
Update
.envfile:- Replace
JWT_SECRETwith your generated value - Update database passwords
- Update Redis password
- Update Elasticsearch password
- Update Grafana admin password
- Adjust other configuration values as needed
- Replace
- Never commit
.envfile to version control - it contains sensitive credentials - Always use cryptographically secure random generators for secrets (minimum 512 bits for JWT)
- Change all default passwords before deploying to production
- Use different secrets for each environment (development, staging, production)
- The
.env.examplefile is safe to commit and serves as a template
The .env file contains configuration for:
- Database: MySQL connection settings and credentials
- Redis: Cache and distributed lock configuration
- Kafka: Event streaming configuration
- Consul: Service discovery settings
- Elasticsearch: Search and analytics configuration
- JWT: Security token configuration (requires secure secret)
- Ports: Service port assignments
- Monitoring: Prometheus and Grafana settings
Start all services with Docker Compose:
docker-compose up -dView logs:
docker-compose logs -fStop all services:
docker-compose downStop and remove volumes (cleans database data):
docker-compose down -v-
Start infrastructure services:
docker-compose up -d consul mysql kafka redis elasticsearch prometheus grafana
-
Build and run each service individually:
cd api-gateway mvn clean install mvn spring-boot:runRepeat for other services:
ticket-service,user-service,payment-service,notification-service,inventory-service,saga-orchestrator-service.
All services are accessible through the API Gateway at http://localhost:8080:
- Tickets:
http://localhost:8080/tickets/** - Users:
http://localhost:8080/users/** - Payments:
http://localhost:8080/payments/** - Notifications:
http://localhost:8080/notifications/** - Inventory:
http://localhost:8080/inventory/**
Individual services are available on their respective ports:
- API Gateway: http://localhost:8080
- Ticket Service: http://localhost:8081
- User Service: http://localhost:8082
- Payment Service: http://localhost:8083
- Notification Service: http://localhost:8084
- Inventory Service: http://localhost:8085
- Saga Orchestrator Service: http://localhost:8086
Access Swagger UI for interactive API documentation:
- API Gateway: http://localhost:8080/swagger-ui.html
- Ticket Service: http://localhost:8081/swagger-ui.html
- User Service: http://localhost:8082/swagger-ui.html
- Payment Service: http://localhost:8083/swagger-ui.html
- Notification Service: http://localhost:8084/swagger-ui.html
- Inventory Service: http://localhost:8085/swagger-ui.html
- Consul UI: http://localhost:8500 (Service discovery and health)
- Prometheus: http://localhost:9090 (Metrics)
- Grafana: http://localhost:3000 (Default credentials: admin/admin)
- Kibana: http://localhost:5601 (Elasticsearch UI)
All services expose health endpoints via Spring Actuator:
- API Gateway: http://localhost:8080/actuator/health
- Ticket Service: http://localhost:8081/actuator/health
- User Service: http://localhost:8082/actuator/health
- Payment Service: http://localhost:8083/actuator/health
- Notification Service: http://localhost:8084/actuator/health
- Inventory Service: http://localhost:8085/actuator/health
- Saga Orchestrator Service: http://localhost:8086/actuator/health
Each service contains its own application.yml file in src/main/resources/. Key configuration areas include:
- Server ports: Configured per service (8080-8086)
- Database connections: MySQL connection strings and credentials
- Kafka settings: Bootstrap servers and topic configurations
- Redis configuration: Host, port, and connection timeouts
- Consul discovery: Service registration settings
- Circuit breaker: Resilience4j circuit breaker configurations
- Actuator endpoints: Health, metrics, and Prometheus exposure
Databases are automatically created on first startup via init-db.sql:
ticketdb- Ticket Service databaseuserdb- User Service databasepaymentdb- Payment Service databasenotificationdb- Notification Service databaseinventorydb- Inventory Service database
For production deployments, configure the following environment variables:
MYSQL_ROOT_PASSWORD- MySQL root passwordMYSQL_HOST- MySQL host addressMYSQL_PORT- MySQL port (default: 3306)
KAFKA_BOOTSTRAP_SERVERS- Kafka bootstrap servers (default: kafka:9092)KAFKA_ZOOKEEPER_CONNECT- Zookeeper connection string
REDIS_HOST- Redis host (default: redis)REDIS_PORT- Redis port (default: 6379)
CONSUL_HOST- Consul host (default: consul)CONSUL_PORT- Consul port (default: 8500)
ELASTICSEARCH_URIS- Elasticsearch connection URIs (default: http://elasticsearch:9200)
PROMETHEUS_ENABLED- Enable Prometheus metrics (default: true)
Build all services:
mvn clean installBuild a specific service:
cd <service-directory>
mvn clean installRun a service:
mvn spring-boot:runStart all services:
docker-compose up -dStart specific services:
docker-compose up -d consul mysql kafka redisView service logs:
docker-compose logs -f <service-name>View all logs:
docker-compose logs -fStop all services:
docker-compose downRebuild and restart:
docker-compose up -d --buildCheck service health:
curl http://localhost:8080/actuator/healthCheck Consul services:
curl http://localhost:8500/v1/agent/servicesThe project structure supports comprehensive testing. Each service can include unit tests, integration tests, and end-to-end tests.
Run all tests:
mvn testRun tests for a specific service:
cd <service-directory>
mvn testGenerate test coverage reports:
mvn clean test jacoco:reportCoverage reports are generated in target/site/jacoco/index.html for each service.
For development and testing environments, use Docker Compose:
docker-compose up -dThe project includes Kubernetes manifests in the k8s/ directory for production deployment.
-
Create namespace:
kubectl apply -f k8s/namespace.yaml
-
Deploy services:
kubectl apply -f k8s/deployments/ kubectl apply -f k8s/services/
-
Configure ingress:
kubectl apply -f k8s/ingress/
-
Set up autoscaling (optional):
kubectl apply -f k8s/autoscaling/
- Use external MySQL, Kafka, Redis, and Elasticsearch clusters
- Configure proper secrets management (Kubernetes Secrets, HashiCorp Vault)
- Set up proper monitoring and alerting
- Configure resource limits and requests
- Enable TLS/SSL for all external communications
- Implement proper backup strategies for databases
- Configure log aggregation (ELK stack, Loki, etc.)
- Set up CI/CD pipelines for automated deployments
Services communicate asynchronously through Kafka topics:
ticket-created- Published when a ticket is createdticket-confirmed- Published when a ticket is confirmedticket-cancelled- Published when a ticket is cancelledpayment-initiated- Published when payment is initiatedpayment-completed- Published when payment succeedspayment-failed- Published when payment failsuser-created- Published when a user is created
The Saga Orchestrator coordinates distributed transactions:
- Receives
TicketCreatedEvent - Coordinates payment processing
- Handles compensation on failures
- Manages saga state and recovery
Ticket Service implements Command Query Responsibility Segregation:
- Commands: CreateTicketCommand, CancelTicketCommand, UpdateTicketStatusCommand
- Queries: Separate read models optimized for querying
- Circuit Breaker: Prevents cascading failures (Resilience4j)
- Retry: Automatic retry for transient failures
- Distributed Locking: Redis-based locking for inventory operations
- Caching: Redis caching for frequently accessed data
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow Java coding standards and best practices
- Write unit tests for new features
- Update documentation as needed
- Ensure all tests pass before submitting PR
- Follow the existing code style and architecture patterns
This project is licensed under the MIT License - see the LICENSE file for details.
This project uses automated CI/CD pipelines and code quality tools:
- Continuous Integration: GitHub Actions workflows run on every push and pull request
- Security Scanning: CodeQL analyzes code for security vulnerabilities
- Code Quality: SonarCloud tracks code quality metrics and technical debt
- Code Coverage: JaCoCo generates test coverage reports uploaded to Codecov
- Dependency Management: Dependabot automatically creates PRs for dependency updates
- Code Style: Checkstyle enforces Google Java Style Guide
# Run checkstyle
mvn checkstyle:check
# Run tests with coverage
mvn clean test jacoco:report
# View coverage report
# Open target/site/jacoco/index.html in your browser
# Run SonarCloud analysis (requires SONAR_TOKEN)
mvn clean verify sonar:sonar \
-Dsonar.projectKey=serhatsoysal_ticket-system \
-Dsonar.organization=serhatsoysalFor questions or support, please contact the development team.
