Question : What are the design patterns are used in microservices ?
In microservices architecture, several design patterns are commonly used to solve specific challenges related to service decomposition, communication, data management, resilience, and scalability. Here’s a categorized list of key microservices design patterns:
1. Decomposition Patterns
Used to break down a monolith into microservices.
-
Decompose by Business Capability: Each microservice is aligned with a specific business function.
-
Decompose by Subdomain (from Domain-Driven Design): Each service represents a bounded context
2. Integration/Communication Patterns
How services interact with each other.
-
API Gateway: A single entry point for all client interactions.
-
Aggregator: Combines results from multiple services into a single response.
-
Proxy: Forwards requests to appropriate services.
-
Client-Side Service Discovery: Clients determine the location of services.
-
Server-Side Service Discovery: A load balancer or gateway routes the request.
📦 3. Database Patterns
How data is handled across services.
-
Database per Service: Each microservice has its own database.
-
Shared Database (less recommended): Multiple services share one database.
-
Saga Pattern: For managing distributed transactions across services.
-
CQRS (Command Query Responsibility Segregation): Separates read and write operations.
-
Event Sourcing: State changes are stored as a sequence of events.
🔁 4. Reliability & Resilience Patterns
To handle faults and ensure reliability.
-
Circuit Breaker: Prevents cascading failures by stopping calls to a failing service.
-
Retry: Automatically retries failed operations.
-
Timeout: Limits the waiting time for a response.
-
Bulkhead: Isolates failures to prevent system-wide impact.
-
Fallback: Provides an alternative response when a service fails.
📢 5. Messaging Patterns
For asynchronous communication between services.
-
Message Broker: Services communicate via a broker (e.g., Kafka, RabbitMQ).
-
Event-Driven Architecture: Services emit and react to events.
-
Publish/Subscribe: Services subscribe to topics and receive events.
-
Choreography: Services collaborate without a central coordinator.
-
Orchestration: A central service coordinates the flow of activities.
🚀 6. Deployment Patterns
To support scalable and efficient deployment.
-
Service Instance per Host/Container: Each service runs in its own container/VM.
-
Service per Team: Ownership aligned with teams.
-
Sidecar Pattern: Pairs a helper container with a main container (e.g., for logging, service mesh proxies like Envoy).
🕵️♂️ 7. Observability & Monitoring Patterns
For logging, tracing, and monitoring.
-
Log Aggregation: Centralizing logs using tools like ELK stack.
-
Distributed Tracing: Tracing requests across services (e.g., OpenTelemetry, Jaeger).
-
Health Check API: Services expose their health status.
Question : What is CQRS pattern in microservices ?
CQRS (Command Query Responsibility Segregation) is a design pattern commonly used in microservices architecture to separate read and write operations into different models. This helps improve scalability, maintainability, and performance, especially for systems with complex business logic or high read/write loads.
🧩 What is CQRS?
-
Command = Write operation (e.g., Create, Update, Delete)
-
Query = Read operation (e.g., Get, Search)
Instead of using the same model and data store for both, CQRS separates them.
🔄 How it works:
-
Command Side:
-
Handles writes (mutations)
-
Performs business logic and validation
-
Uses a different model (Command Model)
-
Typically uses event sourcing or database transactions
-
-
Query Side:
-
Handles reads
-
Optimized for fast querying
-
May use denormalized or cached data
-
Uses its own data store or read model
-
🏗️ Typical CQRS Flow in Microservices:
-
User sends a command (
POST /orders
) -
The command is handled by a write service
-
The service updates its write database
-
It emits an event (
OrderCreated
) -
The read service listens to the event and updates its read database
-
User sends a query (
GET /orders/123
) -
The query service reads from the optimized read database
✅ Benefits of CQRS in Microservices:
-
Scalability: Read and write services can scale independently
-
Performance: Read models can be highly optimized
-
Separation of Concerns: Simpler, more focused services
-
Flexibility: Different technologies for read and write sides
-
Supports Event Sourcing: Naturally fits systems that use event-driven architecture
⚠️ Challenges:
-
Complexity: More moving parts and eventual consistency
-
Data synchronization: Keeping read and write models in sync via events
-
Eventual consistency: Not suitable for all systems (e.g., financial apps needing strong consistency)
🔧 Example Use Case:
In an e-commerce system:
-
Write model handles new orders, updates inventory.
-
Read model gives fast product searches, order summaries using denormalized views.
The Circuit Breaker pattern is a resilience and fault-tolerance design pattern used in microservices to prevent cascading failures when one service depends on another that may be slow, unresponsive, or failing.
What is a Circuit Breaker?
It works just like an electrical circuit breaker. When a downstream service fails repeatedly, the circuit "breaks" and halts further attempts for a while, allowing the system to recover and preventing overload.
🧠 Why it's needed in Microservices:
In a distributed system:
-
Services often call other services (e.g.,
Service A -> Service B
) -
If Service B is down or slow, Service A may get stuck waiting or retrying
-
This can consume resources and eventually cause a chain reaction of failures
-
Circuit breaker protects Service A from being taken down by failures in Service B
🟢🔴🟡 Circuit Breaker States:
-
Closed (Normal)
-
All requests go through.
-
Failures are counted.
-
-
Open (Tripped)
-
Too many failures → circuit opens.
-
No requests are forwarded to the failing service.
-
Returns fallback/fast-failure immediately.
-
-
Half-Open (Trial)
-
After a timeout, a few test requests are allowed.
-
If successful, circuit closes (recovery).
-
If failure continues, circuit re-opens.
-
✅ Benefits:
-
Prevents wasting resources on failing services
-
Helps system self-heal after issues
-
Enables fallback mechanisms (default responses, cache, etc.)
-
Improves resilience and uptime
🧰 Tools & Libraries:
-
Resilience4j (Java/Spring Boot)Hystrix (Netflix – deprecated, but historically important)
-
Istio / Envoy (Service mesh level)
-
Polly (.NET)
-
Sentinel (Alibaba, Java)
-
- Large, complex applications:When dealing with complex systems, microservices can simplify development, testing, and deployment by allowing teams to work on individual services independently.
- Cloud-based systems:Microservices are well-suited for cloud environments, allowing for easier scaling, deployment, and management of distributed applications.
- High availability:Microservices architecture can improve fault tolerance and make it easier to maintain high availability.
- Fast-paced development and deployment:Microservices enable teams to develop, test, and deploy individual services more quickly, facilitating continuous delivery and faster time-to-market.
- Agile development and business agility:Microservices support agile methodologies, allowing for faster iteration and adaptation to changing business needs.
- Integrating business capabilities:They can help integrate different business functions and legacy systems.
- Small, simple applications:For very small or simple applications, the overhead of setting up and managing a microservices architecture may not be justified.
- Tight integration requirements:If different parts of the application need to be tightly coupled and require frequent coordination, microservices might add unnecessary complexity.
- When a monolithic architecture is sufficient:If a simple monolithic application meets your needs and requirements, there's no need to overcomplicate things with microservices.
- Initial lack of expertise:Transitioning to microservices can be challenging, especially for teams lacking experience with distributed systems and microservices development.
What do you mean by Microservice?
Microservices, also known as Microservices Architecture, is basically an SDLC approach in which large applications are built as a collection of small functional modules. It is one of the most widely adopted architectural concepts within software development. In addition to helping in easy maintenance, this architecture also makes development faster. Additionally, microservices are also a big asset for the latest methods of software development such as DevOps and Agile. Furthermore, it helps deliver large, complex applications promptly, frequently, and reliably. Applications are modeled as collections of services, which are:
- Maintainable and testable
- Loosely coupled
- Independently deployable
- Designed or organized around business capabilities
- Managed by a small team.
1. What are microservices?
Microservices is an architectural style where an application is built as a collection of small, independent services that communicate over lightweight protocols like HTTP or messaging queues. Each service focuses on a specific business capability, ensuring loose coupling and high cohesion.
2. What are the key features of microservices architecture?
- Decentralized governance: Independent teams for development.
- Componentization: Each service is a component.
- Flexibility in technology: Services can use different tech stacks.
- Scalability: Services can scale independently.
- Resilience: Faults are isolated.
3. How do microservices communicate with each other?
Microservices communicate through:
- Synchronous communication: HTTP/REST APIs, gRPC.
- Asynchronous communication: Message brokers like RabbitMQ, Kafka, or JMS.
4. How do you handle service discovery in microservices?
Service discovery is implemented using tools like:
- Client-side discovery: Services register with a service registry (e.g., Eureka, Consul).
- Server-side discovery: Services register, and the API Gateway resolves requests using a registry.
5. What is the role of an API Gateway in microservices?
API Gateways handle:
- Routing requests to appropriate services.
- Load balancing.
- Authentication and authorization.
- Caching and monitoring.
Examples: Spring Cloud Gateway, Kong, NGINX.
6. How do you handle distributed transactions in microservices?
Using SAGA patterns, such as:
- Choreography: Events trigger local transactions.
- Orchestration: A central controller manages transaction states.
Tools like Camunda and Axon can help manage SAGA workflows.
7. What challenges arise in microservices testing?
- Service dependencies: Hard to isolate services.
- Data consistency: Distributed systems lead to eventual consistency.
- Integration testing: Requires mock services.
- Performance: Monitoring inter-service latency.
8. What is eventual consistency? How is it handled?
In distributed systems, eventual consistency means all data replicas will synchronize over time. It’s achieved through:
- Event-driven architecture: Using Kafka, RabbitMQ.
- CQRS: Separating command and query models.
9. How do you ensure fault tolerance in microservices?
- Retry mechanisms: Retry failed calls.
- Circuit breakers: Using libraries like Hystrix, Resilience4j.
- Fallbacks: Provide default responses.
- Bulkheads: Isolate resources for critical services.
10. How do you handle inter-service communication failure?
- Implement timeouts and retries.
- Use circuit breakers.
- Implement fallback mechanisms.
11. What is the role of Docker and Kubernetes in microservices?
- Docker: Containerizes microservices for consistency across environments.
- Kubernetes: Orchestrates and manages containers, ensuring scaling, high availability, and load balancing.
12. How do you ensure security in microservices?
- Authentication and authorization: Use OAuth 2.0 and JWT.
- API Gateway: Centralized security policies.
- Secure communication: Use HTTPS and mutual TLS.
- Secrets management: Use tools like Vault.
13. What are sidecars in microservices?
Sidecars are helper containers that run alongside main service containers to handle cross-cutting concerns like logging, monitoring, and security.
14. What is service mesh?
A service mesh (e.g., Istio, Linkerd) is a dedicated infrastructure layer that handles inter-service communication, security, and observability.
15. How do you monitor microservices?
- Tools: Prometheus, Grafana, ELK stack, Jaeger, Zipkin.
- Metrics: CPU, memory, request latency, error rates.
16. How do you deploy microservices?
- Containerized deployments: Docker + Kubernetes.
- CI/CD pipelines: Tools like Jenkins, GitHub Actions.
- Canary deployments: Gradual release to a subset of users.
- Blue-Green deployments: Parallel environments.
17. What is DDD (Domain-Driven Design) in microservices?
DDD emphasizes creating services around business domains with clearly defined boundaries, ensuring better modularity and separation.
18. How do you handle data sharing between microservices?
- Database per service: Services have their own databases.
- Event-driven communication: Use events to share updates.
- API queries: Services expose read-only APIs.
19. What are idempotent operations in microservices?
An idempotent operation produces the same result no matter how many times it’s executed (e.g., DELETE request in REST).
20. How do you manage configuration in microservices?
- Externalized configurations: Using tools like Spring Cloud Config or Consul.
- Environment-specific settings: Separate configurations per environment.
21. What is bounded context in microservices?
A bounded context is a DDD concept where each microservice owns a well-defined business area to avoid overlaps and dependencies.
22. How do you handle versioning in REST APIs?
- URI versioning:
/v1/resource
. - Header versioning:
Accept: application/vnd.api.v1+json
. - Query parameters:
?version=1
.
23. What are anti-patterns in microservices?
- Shared database: Coupling between services.
- Over-engineering: Adding microservices unnecessarily.
- Too fine-grained services: Leads to performance issues.
24. What is the 12-factor app methodology?
Guidelines for building scalable and portable applications, covering aspects like configuration, logging, dependency management, and disposability.
25. What is a distributed log aggregator, and why is it used?
A distributed log aggregator collects logs from all microservices. Tools like the ELK stack and Fluent Id are used for centralized logging and troubleshooting.
25 .Explain the design patterns of Java Spring Boot Microservices.
- Service Registry and Discovery: Services automatically register in a central registry, allowing others to identify and interact with them dynamically.
- API Gateway: It acts as a customer entry point and forwards requests to appropriate microservices to provide additional functionality such as authentication and rate limits.
- Circuit Breaker: It monitors the availability of services and protects from failures by sending requests or by providing responses if service is unavailable.
- CQRS (Command Query Responsibility Segregation): It separates the read and write operations. Also, it optimizes each and every operation separately for efficiency.
- Saga Pattern: It manages distributed tasks by organizing a sequence of local transactions.
- Database per service: Each of the services has separate databases. This ensures data isolation and also enables scaling and individual development.
- Asynchronous messaging: Each services communicate with each other through message queues like Kafka or RabbitMQ.
26. What are the Main Components of Java Spring Boot Microservices?
The main components of Java Spring Boot Microservices include:
- Services
- Service Registry
- API Gateway
- Cloud Infrastructure
- Containerization and Orchestration
- Message Broker
- Security
- Monitoring.
In Microservices, multiple services run independently. Services communicate with each other through,
- HTTP/REST: These are light-weight protocols used for perform communication between two services.
- Message queues: Message queues such as Kafka or RabbitMQ used to make connection.
- RPC (Remote Procedure Call) Framework: RPC frameworks such as gRPC uses in services for communication purposes.
These methods of communication enable loosely coupled interaction, scalability, and flexibility in distributed systems.
28. How to Process the Request and Response between Two Services?
By establishing communication between the two services, microservices can handle requests and responses between any two services using XML (Extensible Mark-up Language) and JSON (JavaScript Object Notation).
- XML and JSON are data exchange formats and it helps to generate requests and responses between two services.
- Most important thing is the data exchange format and both the services have to know the data exchange format to request and respond accordingly.
- If we compare both formats, JSON is very simple to use in Microservices.
FeignClient is known as Spring Cloud OpenFeign.
- It is a declarative REST Client in Spring Boot Web Application. Declarative REST Client means to specify the client specification as an Interface and spring boot will take care of the implementation.
- With the help of FeignClient, writing web services is very simple.
- It is mostly used to consume REST API endpoints exposed by third parties or microservices.
We can use FeignClient for Java Microservices Communication by the following approach:
Add this dependency to the pom.xml file.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
After adding the library, add this @EnableFeignClients annotation to the main Application file as below:
@SpringBootApplication
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Create an Interface and define it with @FeignClient annotation and declare calling method as below:
@FeignClient(name = "giveHereServiceName", url = "provideUrlHere", path = "provideContextPathHere")
public interface AddressClient {
@GetMapping("/address/{id}")
public ResponseEntity<AddressResponse> getAddressByEmployeeId(@PathVariable("id") int id);
}
Now it is ready to be used in the service class file. You can see the below code:
@Service
public class EmployeeService {
// More Code Here
// -------------
// Spring will create the implementation
// for this class
// and here it will insert the bean (proxy) .
@Autowired
private AddressClient addressClient;
public EmployeeResponse getEmployeeById(int id) {
// More Code Here
// Using FeignClient
ResponseEntity<AddressResponse> addressResponse = addressClient.getAddressByEmployeeId(id);
employeeResponse.setAddressResponse(addressResponse.getBody());
return employeeResponse;
}
}
No comments:
Post a Comment