🔍 What are Microservices?
Microservices is an architectural style application. It has collection of loosely coupled, independently deployable services, and each service is responsible for a specific business function.
Instead of building a monolithic application, microservices allow you to divide functionality (like User, Order, Notification, etc.) into separate components that:
Microservices are developed, deployed, and scaled independently
Microservices communicate via lightweight protocols (e.g., HTTP/REST, gRPC, Kafka)
Microservices can be written in different programming languages (polyglot)
Microservices are organized around business capabilities
✅ Key Characteristics
| Feature | Description |
|---|---|
| Decentralized | Each service has its own logic and database. |
| Scalable | Services can be scaled independently. |
| Resilient | If any service is failed then don't affect the whole system. |
| Deployable | Services can be deployed independently without full app restart. |
| Technology-agnostic | You can use different tools or languages for different services. |
| Layer | Common Tools |
|---|---|
| Framework | Spring Boot, Micronaut, Quarkus |
| API Gateway | Spring Cloud Gateway, Zuul, NGINX |
| Service Discovery | Eureka, Consul, Zookeeper |
| Communication | REST (WebClient), RestTemplate, Kafka, gRPC, RabbitMQ |
| Configuration | Spring Cloud Config, Consul |
| Security | Spring Security + OAuth2/JWT |
| Resilience | Resilience4j, Hystrix |
| Observability | Sleuth, Zipkin, Prometheus + Grafana, ELK stack |
| Packaging/Deployment | Docker, Kubernetes, Jenkins, Helm |
🔁 Communication Between Services
-
Synchronous:
-
REST API using
WebClientorRestTemplate -
gRPC for high-performance binary communication
-
-
Asynchronous:
-
RabbitMQ or Kafka for event-driven architecture
-
✅ Advantages of Microservices
-
✅ Better scalability and flexibility
-
✅ Faster development and deployment cycles
-
✅ Improved fault isolation and maintainability
-
✅ Independent tech stacks and database per service
⚠️ Challenges of Microservices
| Challenge | Solution |
|---|---|
| Distributed logging | Use centralized logging (ELK, Fluentd) |
| Service communication | API Gateway, Circuit Breakers |
| Data consistency | Event-driven architecture (Kafka), Sagas |
| Security | JWT, OAuth2, centralized authentication service |
| Deployment complexity | Docker + Kubernetes, CI/CD pipelines |
| Recommended If... | Avoid If... |
|---|---|
| You need scalability | Your app is small/simple |
| You want independent team delivery | You have tight resources |
| You expect rapid evolution of components | You're unfamiliar with DevOps tooling |
Microservices in Java (especially using Spring Boot) is a powerful way to build scalable, modular, and maintainable applications. It is widely used in enterprise systems, fintech, e-commerce, and cloud-native applications.
---------------------------------
2).How many ways communicate spring boot with microservices
Spring Boot can communicate with other microservices in multiple ways, depending on the architecture style, protocol, and purpose. Below are all the major ways Spring Boot microservices can communicate with each other, grouped by synchronous vs asynchronous communication:
🔹 1. Synchronous Communication (Request/Response)
In synchronous communication, one service waits for the response from another.
✅ a. RESTful HTTP using RestTemplate (legacy but still used)
-
RestTemplateis a synchronous HTTP client to call other microservices. -
Common for simple, blocking calls.
✅ b. RESTful HTTP using WebClient (preferred for non-blocking)
-
Part of Spring WebFlux, supports reactive programming.
-
Recommended over
RestTemplatefor non-blocking I/O.
✅ c. Feign Client (Declarative REST client)
-
Part of Spring Cloud OpenFeign.
-
Auto-load-balances with Eureka + Ribbon.
-
Simplifies REST call with interface and annotations.
✅ What is Feign?
Feign is a declarative HTTP client developed by Netflix and integrated into Spring Cloud. Instead of manually writing code to call REST APIs using RestTemplate or WebClient, you define an interface and annotate it with @FeignClient.
2. Asynchronous Communication (Event-Driven)
Services communicate using events, without waiting for a response.
✅ a. Apache Kafka
-
Distributed event-streaming platform.
-
Suitable for real-time data pipelines.
Producer
Consumer
✅ b. RabbitMQ (AMQP)
-
Message broker for asynchronous messaging.
-
Spring Boot supports it with
spring-boot-starter-amqp.
🔹 3. Service Discovery (for REST/Kafka)
Helps microservices find each other dynamically.
✅ a. Eureka Server (Spring Cloud Netflix Eureka)
-
Services register with Eureka.
-
Enables dynamic discovery for REST, Feign, Kafka, etc.
🔹 4. API Gateway Communication
All calls go through a central API Gateway for routing, filtering, auth, etc.
✅ a. Spring Cloud Gateway
-
Reactive API gateway for routing requests to downstream services.
-
Can integrate with discovery and load balancing.
🔹 5. gRPC (Binary Protocol)
High-performance communication using protocol buffers.
-
Faster and more efficient than REST.
-
Requires proto files and code generation.
🔹 6. RSocket
Reactive protocol over WebSocket/TCP/HTTP for bidirectional streaming.
-
Low-latency, supports request-response and streaming.
-
Useful in reactive microservices.
🔹 7. GraphQL Federation
Communicate via GraphQL queries if you use federated services.
-
Each service exposes a schema.
-
Central gateway composes full schema.
🔹 8. Shared Database / Event Store (Not recommended for true microservices)
-
Services read/write to the same database or event log (e.g., Event Sourcing).
-
Used only when data ownership or CQRS applies.
🔹 9. File-based Communication / FTP / Shared Storage
-
Rare, but useful for legacy integration.
✅ Summary Table
| Method | Type | Use Case | Tech Stack |
|---|---|---|---|
| RestTemplate | Sync | Simple REST calls | Spring MVC |
| WebClient | Sync | Non-blocking calls | Spring WebFlux |
| Feign Client | Sync | Declarative REST + Load Balancing | Spring Cloud |
| Kafka | Async | Event-driven, real-time messaging | Kafka, Spring Kafka |
| RabbitMQ | Async | Message Queues | Spring AMQP |
| gRPC | Sync/Async | High-performance binary messaging | Spring Boot + gRPC |
| RSocket | Async | Reactive streaming communication | RSocket + Spring Boot |
| Eureka | Discovery | Dynamic service registration/discovery | Spring Cloud Netflix Eureka |
| Spring Gateway | Sync | Central API Gateway | Spring Cloud Gateway |
2) Kubernetes DNS with Spring Boot microservices, Docker, and RestTemplate — with no Eureka or service registry.
Here's a complete step-by-step guide to use Kubernetes DNS with Spring Boot microservices, Docker, and RestTemplate — with no Eureka or service registry.
✅ Goal
You want:
-
Multiple Spring Boot microservices
-
Communication via
RestTemplate -
Service Discovery via Kubernetes DNS
-
Packaged in Docker containers
-
Deployed to Kubernetes
🧱 Microservices Architecture Example
Let's assume two services:
-
user-service(Provider) -
order-service(Consumer that callsuser-serviceusingRestTemplate)
🔧 1. Spring Boot Configuration
✅ In order-service
💡
http://user-serviceis the Kubernetes DNS name. You don't need Eureka.
✅ Configuration Class for RestTemplate
Do not use
@LoadBalanced— it’s needed only when using Spring Cloud LoadBalancer or Eureka.
✅ application.yml
You only need basic configuration:
🐳 2. Dockerfile for Both Services
🧱 Build and Push
☸️ 3. Kubernetes Deployment & Service YAMLs
✅ user-service.yaml
✅ order-service.yaml
🌐 4. Deploy and Verify in Kubernetes
🔍 Test DNS:
From order-service pod:
🧠 How DNS Works in Kubernetes
Kubernetes creates DNS entries for every service:
-
http://user-service= internal service name -
Optional full DNS:
http://user-service.default.svc.cluster.local
So your RestTemplate will automatically resolve the DNS via internal service discovery.
✅ Summary: Configurations Needed
| Area | Configuration |
|---|---|
| Spring Boot App | Use RestTemplate with http://<service-name> |
RestTemplate Bean | No @LoadBalanced, just plain new RestTemplate() |
| Service Naming | Match Feign or REST URLs to Kubernetes Service names |
| Docker | Build Docker images of each service |
| Kubernetes | Deployments + Services for each microservice |
| Service Discovery | Handled by Kubernetes DNS (no Eureka, Consul, etc.) |
If we use Java 17, make HTTP calls (GET, POST, PUT, DELETE) communicate to microservices
✅ Full Java 17 Code – Clean Microservice Communication
1. Product.java – POJO to represent request/response
2. MicroserviceHttpClient.java – main class to call services
✅ Dependencies (for Jackson):
Add the following to your pom.xml if using Maven:
✅ Summary
-
✅ Java 17 standard HTTP client — no Spring
-
✅ Object-based JSON using Jackson (
Productclass) -
✅ Covers
GET,POST,PUT,DELETEwith clean structure -
✅ No hardcoded JSON strings
🧩 MICROservices DESIGN PATTERNS
1. Aggregator / API Gateway Pattern
What:
An API Gateway acts as a single entry point for all clients. It aggregates multiple microservices' results and returns a single response.Why:
-
Simplifies client interactions
-
Reduces client-side complexity
-
Adds cross-cutting concerns like authentication, rate-limiting, and logging
When to Use:
-
When you have multiple microservices but want the client to make a single request
-
When mobile/web apps shouldn’t manage multiple service endpoints
Example:
Client → API Gateway → [User Service + Order Service + Inventory Service] → Aggregated Response2. Circuit Breaker Pattern
What:
The Circuit Breaker Pattern is a design pattern used in microservice and distributed system architectures to detect failures and prevent an application from repeatedly trying to execute an operation that is likely to fail.
It temporarily blocks access to a failing service after a defined number of consecutive failures and allows retry only after a cooldown period, thereby improving system resilience, stability, and fault tolerance.
Why:
-
Prevents cascading failures
-
Improves fault tolerance
-
Provides fallback mechanisms
When to Use:
-
When calling a remote service that may become unresponsive
-
During timeouts and repeated failures
Example:
Hystrix, Resilience4j libraries can be used
If Inventory Service is down → Circuit opens → Short-circuits future requests → Returns default message3. Chain of Responsibility Pattern
What:
Each microservice handles a part of a request and passes it to the next in a sequence.Why:
-
Breaks down processing into manageable steps
-
Makes the system extensible and decoupled
When to Use:
-
When processing requires multiple sequential tasks
-
For order fulfillment, data validation chains, etc.
Example:
Order Microservice → Inventory → Payment → Notification4. Asynchronous Messaging Pattern
What:
Microservices communicate via messaging systems (e.g., Kafka, RabbitMQ) instead of direct HTTP.Why:
-
Decouples services
-
Improves scalability
-
Supports event-driven architecture
When to Use:
-
When real-time sync is not required
-
When handling high traffic or batch jobs
Example:
User registers → Auth Service publishes "UserCreated" event → Email Service consumes event and sends welcome mail5. Database per Service Pattern
What:
Database per Service is a microservices architecture pattern where each service owns and manages its own database schema, rather than sharing a common one across multiple services.Why:
-
Promotes loose coupling
-
Prevents cross-service data dependencies
-
Improves autonomy
When to Use:
-
In all microservice architectures
-
Avoid shared database schemas
Example:
-
User Service uses PostgreSQL
-
Order Service uses MySQL
-
Inventory Service uses MongoDB
6. Event Sourcing Pattern
What:
Event Sourcing is a design pattern where every change to the application state is stored as a sequence of events, rather than storing just the current state. The current state is derived by replaying these events in order.Why:
-
Full history of changes
-
Enables audit logs, rollback, and replay
-
Improves scalability and traceability
When to Use:
-
In complex domain models
-
When audit/history is required
Example:
Instead of just saving "Order Delivered", save events like:
OrderPlaced → OrderPacked → OrderShipped → OrderDelivered7. Shared Data Pattern (Anti-pattern)
What:
The Shared Data Pattern (considered an anti-pattern in microservices) occurs when multiple services access the same database or schema, leading to tight coupling between services and potential data integrity issues.Why It's Bad:
-
Tight coupling
-
Schema changes break multiple services
-
Leads to performance issues and data integrity problems
Avoid it by:
-
Using Database per Service
-
Communicating via APIs or messaging
---------------------------
-
✅ 1) Session Management in Microservices
In Microservices architecture, session management is challenging because services are stateless by design—they do not retain any user session information between requests. To maintain authentication and user context across requests and services, specific strategies must be used.
Common approaches are
Best Practice:
Use JWT with API Gateway for stateless, scalable session handling.
✅ 2) Service Discovery in Microservices
Service discovery allows microservices to find and communicate with each other dynamically without hardcoding IPs.
There are two types: Client-side (e.g., Eureka) and Server-side (e.g., Kubernetes, Consul).
Services register with a service registry, and consumers query it to find instances.
This enables scaling, resilience, and dynamic load balancing.
Microservices communicate using REST APIs, gRPC, or message brokers like Kafka or RabbitMQ.
For synchronous communication, services use HTTP calls (via RestTemplate, WebClient, or Feign).
For asynchronous communication, they publish/subscribe to event streams.
Service discovery and API Gateway often help route and manage service-to-service communication.
Security, retries, timeouts, and circuit breakers (like Resilience4j) should be implemented for reliability.