Microservices-Deep Drive
- Anand Nerurkar
- May 4
- 5 min read
✅ Section 1: Technical Deep Dive
1. What is microservices architecture? How is it different from monolithic architecture?
Answer:Microservices architecture is an approach where an application is composed of small, loosely coupled, independently deployable services. Each service focuses on a specific business capability and communicates via lightweight protocols (typically HTTP or messaging queues).
Differences:
Monolith | Microservices |
Single codebase | Multiple independent services |
Tight coupling | Loose coupling |
Shared DB | Independent DBs |
Hard to scale selectively | Scalable per service |
Single point of failure | Resilient and fault-tolerant |
2. What are the key benefits and challenges of using microservices?
Benefits:
Independent deployment
Technology diversity
Scalability per service
Improved fault isolation
Aligned with Agile/DevOps
Challenges:
Complexity in distributed systems
Data consistency
Inter-service communication
DevOps sophistication needed
Testing and monitoring become harder
3. How do microservices communicate with each other?
Answer:
Synchronous (HTTP/REST, gRPC): Easy to implement, but tightly coupled and prone to cascading failures.
Asynchronous (Kafka, RabbitMQ): Decoupled, more scalable, resilient, but harder to debug and ensure delivery guarantees.
4. What is service discovery and how is it implemented?
Answer:Service discovery helps microservices locate each other dynamically. Implemented using:
Client-side discovery (e.g., Netflix Eureka with Ribbon)
Server-side discovery (e.g., AWS ALB, Consul)
Service mesh (e.g., Istio + Envoy)
5. How do you handle data consistency in microservices?
Answer:
Prefer eventual consistency
Use Saga pattern for long-running transactions (choreography or orchestration)
Event-driven architecture to propagate state changes
Avoid distributed transactions if possible
6. Explain the role of API Gateway.
Answer:Acts as a single entry point for client requests. Responsibilities:
Request routing
Authentication/Authorization
Rate limiting
Logging/Monitoring
Load balancing
Examples: Kong, NGINX, AWS API Gateway, Spring Cloud Gateway
7. How do you handle API versioning?
Answer:
URI-based (/api/v1/resource)
Header-based (Accept: application/vnd.api.v1+json)
Query param-based (?version=1)Ensure backward compatibility and deprecate carefully.
🔷 Use Case: Customer Account Management Microservice in a Banking Platform
Let’s say you have a CustomerAccountService microservice responsible for:
Fetching customer details
Opening new accounts
Managing account preferences
Initially, it exposes this endpoint:
bash
CopyEdit
GET /api/accounts/{customerId}
Later, you need to support enhanced account types (e.g., wealth, NRI, etc.) without breaking older mobile/web clients.
🔷 Strategy: How to Handle API Versioning
✅ 1. URL Path Versioning (Most Common & Recommended for Microservices)
Version is added in the URL path:
bash
CopyEdit
GET /api/v1/accounts/{customerId} GET /api/v2/accounts/{customerId}
v1 supports basic details.
v2 supports extended account metadata like accountType, investmentPortfolio, etc.
Spring Boot Example:
java
CopyEdit
@RestController @RequestMapping("/api/v1/accounts") public class AccountControllerV1 { @GetMapping("/{id}") public AccountV1 getAccount(@PathVariable String id) { // Basic account info } } @RestController @RequestMapping("/api/v2/accounts") public class AccountControllerV2 { @GetMapping("/{id}") public AccountV2 getAccount(@PathVariable String id) { // Extended info with portfolio } }
✅ 2. Header Versioning (Good for internal APIs)
Clients pass a custom header like:
pgsql
CopyEdit
GET /api/accounts/{customerId} Header: X-API-VERSION: 2
This avoids cluttering URLs and works well with Spring Boot using custom @RequestMapping condition.
✅ 3. Query Param Versioning (Not very RESTful)
pgsql
CopyEdit
GET /api/accounts/{customerId}?version=2
Used mostly for internal microservices-to-microservices calls, not external/public APIs.
✅ 4. Media Type Versioning (a.k.a. Content Negotiation)
Clients use Accept headers:
bash
CopyEdit
Accept: application/vnd.bank.account.v1+json
Advanced, but adds parsing complexity.
🔷 Best Practices in a Banking Environment
Principle | Why It's Important |
Backward Compatibility | Old mobile/web clients shouldn’t break when APIs change |
Deprecation Strategy | Announce and phase out older versions with monitoring |
Documentation | Clearly maintain Swagger/OpenAPI for each version |
Security | Secure all versions equally using Azure AD + OAuth2 |
Traffic Routing | Use Azure API Management or Istio Gateway to route per version |
Telemetry | Track version usage in Azure Monitor or App Insights |
🔷 Deployment on Azure
Expose versions in Azure API Management as separate APIs (v1, v2).
Route traffic via Istio VirtualService:
yaml
CopyEdit
- match: - uri: prefix: "/api/v2/" route: - destination: host: accountservice-v2
Monitor usage per version using Azure Monitor + Log Analytics.
8. How do you secure communication between microservices?
Answer:
Use mTLS for service-to-service encryption
Token-based auth (e.g., JWT, OAuth2)
API Gateway for auth and rate-limiting
Use service mesh (e.g., Istio) for consistent policy enforcement
9. What is the role of a service mesh?
Answer:A service mesh handles service-to-service communication transparently. It provides:
Traffic routing
Observability
Security (mTLS)
Retry, timeout, circuit breaking
Examples: Istio, Linkerd, Consul Connect
10. What are sidecars, and how do they help?
Answer:Sidecars are helper containers deployed alongside application containers (in the same pod) in Kubernetes. They provide:
Logging
Service discovery
Proxies (e.g., Envoy)
Security (auth, TLS)
✅ Section 2: Architecture & Design Questions
1. Design a microservices-based architecture for a digital banking platform.
Answer:
Services: Accounts, Payments, Loans, Customer, Auth, Notification
Communication: REST + Kafka (event-driven)
DB per service (PostgreSQL, MongoDB)
API Gateway for aggregation
CI/CD with Jenkins + Docker + Kubernetes
Observability: Prometheus, Grafana, ELK
Security: OAuth2, mTLS, rate limiting
2. How to decompose a monolith into microservices?
Answer:
Identify business domains → create bounded contexts
Use Domain-Driven Design (DDD)
Start with non-critical modules
Use strangler pattern to gradually replace parts
Ensure contracts via APIs
3. Design patterns used in microservices?
Answer:
API Gateway
Circuit Breaker (e.g., Resilience4j)
Saga pattern
CQRS (Command Query Responsibility Segregation)
Service Registry
Sidecar & Ambassador
4. How do you handle distributed transactions?
Answer:Avoid 2PC. Use:
Saga pattern – local transactions + compensating actions
Eventual consistency via events
Orchestrator pattern if coordination needed
5. How to ensure observability?
Answer:
Logging: Centralized via ELK or Fluentd
Metrics: Prometheus + Grafana
Tracing: OpenTelemetry, Jaeger, Zipkin
Dashboards + Alerts: Grafana + Alertmanager
6. CI/CD in microservices ecosystem?
Answer:
CI: Code → Build → Test → Package (Jenkins, GitHub Actions)
CD: Deploy to staging/prod (ArgoCD, Spinnaker)
Containerize each service (Docker)
Use Kubernetes with Helm charts or Kustomize
7. Handling failures in microservices?
Answer:
Retries with exponential backoff
Circuit breaker
Fallback logic
Timeouts
Bulkheads
Alerting and dashboards
8. How to handle schema evolution?
Answer:
Use backward/forward-compatible schemas
Evolve APIs carefully (add new fields, avoid removing required ones)
For events: use Protobuf/Avro with schema registry
Implement consumer-first contracts (Consumer-Driven Contracts)
✅ Section 3: Scenario-Based Questions
1. Intermittent service failure in prod?
Approach:
Check dashboards/logs/alerts
Use distributed tracing to find root cause
Check dependencies and external services
Rollback recent deployments if needed
Add circuit breaker/fallback if pattern detected
2. Service bottleneck due to high traffic?
Approach:
Scale horizontally (add pods/instances)
Optimize code/db queries
Add caching (e.g., Redis)
Use rate limiting or throttle non-critical requests
Offload to async processing (e.g., queue)
3. Fraud detection service needing 4 service integrations?
Answer:
Use async pub-sub model via Kafka for resilience
Retry + circuit breakers for external calls
Aggregate responses if needed using Saga
Ensure observability
Cache frequent responses (if possible)
4. Integrate GenAI-based personalization in microservices?
Answer:
Create a separate AI inference microservice
Use REST/gRPC to invoke GenAI APIs
Use RAG (Retrieval Augmented Generation) for contextual responses
Add monitoring + auto ML model retraining
Ensure latency control (use async if needed)
5. Migrate legacy credit scoring module to microservices?
Answer:
Use strangler pattern
Create new credit scoring microservice in parallel
Route a subset of traffic for A/B testing
Ensure data sync
Gradually increase usage, then retire monolith part
Kommentare