Microservices Architecture
Microservices কেন শিখতে হবে?
আপনি একটা বড় e-commerce app বানাচ্ছো। User login, product catalog, payment, order tracking, notification — সব একটা codebase এ। এক জায়গায় bug হলে পুরো system down। Team বড় হলে merge conflict। Deploy করতে পুরো app restart।
এই সমস্যার সমাধান হলো Microservices Architecture। আজকাল Amazon, Netflix, Uber, Spotify সহ প্রায় সব বড় company এই approach ব্যবহার করে।
DEFINITION
Microservices হলো একটা architectural style যেখানে একটা বড় application কে ছোট ছোট independent services এ ভাগ করা হয়। প্রতিটা service তার নিজের কাজ করে, নিজের database রাখে, এবং network (HTTP/gRPC) এর মাধ্যমে অন্য services এর সাথে communicate করে।
আগে কী ছিল, এখন কী হয়েছে?
দুটো approach এর মূল পার্থক্য বোঝা দরকার — কারণ interview তে এই comparison প্রায়ই আসে।
| বিষয় | Monolith | Microservices |
|---|---|---|
| Deploy | পুরো app একসাথে | প্রতিটা service আলাদা |
| Scale | পুরো app scale করতে হয় | শুধু দরকারী service scale করুন |
| Team | একটা team সব কাজ করে | প্রতিটা service এর আলাদা team |
| Technology | একটাই language/framework | প্রতিটা service ভিন্ন tech |
| Failure | একটা bug সব ভাঙে | একটা service fail হলে বাকিগুলো চলে |
| Database | Shared single database | প্রতিটার নিজের database |
| Complexity | Simple | High (Network, tracing) |
| Startup | Ideal for small teams | Overkill for small apps |
IMPORTANT
Microservices মানে এই না যে সবসময় ভালো। Small startup এ monolith দিয়ে শুরু করা অনেক বেশি sensible। System জটিল হলে, team বড় হলে, তখন microservices এ migrate করুন। Amazon নিজেও monolith দিয়ে শুরু করেছেনিল!
Microservices কীভাবে কাজ করে?
একটা real e-commerce order flow দেখি — user order দিলে কী হয়:
Key Components
API GATEWAY
Single entry point। Client সব request এখানে পাঠায়। Rate limiting, auth, routing সব এখানে handle হয়। (Kong, AWS API Gateway, Nginx)
MESSAGE BUS
Services এর মধ্যে async communication। Direct call না করে event publish করুন। (Kafka, RabbitMQ, AWS SQS)
SERVICE REGISTRY
কোন service কোথায় আছে তার directory। Services নিজেদের register করে। (Consul, Eureka, Kubernetes DNS)
DISTRIBUTED TRACING
Request কোন কোন service এ গেছে track করা। একটা request এর পুরো journey দেখা। (Jaeger, Zipkin, Datadog)
Microservices Design Patterns
1. Database per Service Pattern
প্রতিটা service এর নিজের database থাকবেন। কোনো service অন্য service এর database সরাসরি access করবেন না। এতে loose coupling নিশ্চিত হয়।
WHY IT'S GOOD
2. Saga Pattern (Short Overview)
Multiple services এ একটা transaction। Order service → Payment service → Inventory service। কোনো step fail করলেন rollback। Topic 6 এ বিস্তারিত।
3. CQRS (Command Query Responsibility Segregation)
Read এবং Write এর জন্য আলাদা model। Write operations যায় Command side এ, Read operations যায় Query side এ। High traffic systems এ খুব useful।
Practical Code — Python & Node.js
Python: FastAPI দিয়ে Order Microservice
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import httpx # অন্য service কে call করার জন্য
import asyncio
app = FastAPI(title="Order Service")
# অন্য services এর URL — real এ এটা env variable থেকে আসবেন
PAYMENT_SERVICE_URL = "http://payment-service:8001"
INVENTORY_SERVICE_URL = "http://inventory-service:8002"
class OrderRequest(BaseModel):
user_id: int
product_id: int
quantity: int
total_amount: float
# In-memory DB (real এ PostgreSQL হবে)
orders_db = {}
order_counter = 1
@app.post("/orders")
async def create_order(order: OrderRequest):
global order_counter
async with httpx.AsyncClient() as client:
# Step 1: Inventory check করুন
inv_response = await client.get(
f"{INVENTORY_SERVICE_URL}/check/{order.product_id}/{order.quantity}"
)
if inv_response.status_code != 200:
raise HTTPException(400, "Insufficient inventory")
# Step 2: Payment process করুন
pay_response = await client.post(
f"{PAYMENT_SERVICE_URL}/charge",
json={"user_id": order.user_id, "amount": order.total_amount}
)
if pay_response.status_code != 200:
raise HTTPException(402, "Payment failed")
# Step 3: Order save করুন
order_id = order_counter
orders_db[order_id] = {"id": order_id, "status": "confirmed", **order.dict()}
order_counter += 1
return {"order_id": order_id, "status": "confirmed"}
@app.get("/orders/{order_id}")
async def get_order(order_id: int):
order = orders_db.get(order_id)
if not order:
raise HTTPException(404, "Order not found")
return orderNode.js: Express দিয়ে Payment Microservice
const express = require('express');
const app = express();
app.use(express.json());
// Mock payment processor
const payments = new Map();
app.post('/charge', async (req, res) => {
const { user_id, amount } = req.body;
// Simulate payment processing
if (amount <= 0) {
return res.status(400).json({ error: 'Invalid amount' });
}
const payment_id = `pay_${Date.now()}`;
payments.set(payment_id, {
user_id,
amount,
status: 'success',
timestamp: new Date().toISOString()
});
// Real এ এখানে Stripe/bKash API call হবে
res.json({
payment_id,
status: 'success',
message: `Payment of ৳${amount} processed`
});
});
app.get('/payment/:id', (req, res) => {
const payment = payments.get(req.params.id);
if (!payment) return res.status(404).json({ error: 'Not found' });
res.json(payment);
});
app.listen(8001, () => console.log('Payment service running on :8001'));Docker Compose: Services একসাথে চালানো
version: '3.8'
services:
api-gateway:
image: nginx:alpine
ports: ["80:80"]
volumes: ["./nginx.conf:/etc/nginx/nginx.conf"]
depends_on: [order-service, payment-service, inventory-service]
order-service:
build: ./order_service
ports: ["8000:8000"]
environment:
- DATABASE_URL=postgresql://user:pass@order-db:5432/orders
depends_on: [order-db, kafka]
payment-service:
build: ./payment_service
ports: ["8001:8001"]
inventory-service:
build: ./inventory_service
ports: ["8002:8002"]
order-db:
image: postgres:15
environment:
POSTGRES_DB: orders
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
kafka:
image: confluentinc/cp-kafka:latest
environment:
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181বাস্তব জীবনে Microservices
Netflix
৫০০+ microservices। প্রতিটা Netflix feature আলাদা service। Recommendation, streaming, billing সব আলাদা। প্রতি মাসে ১ billion+ API calls।
Amazon
2-pizza rule: প্রতিটা team এত ছোট হবে যে দুটো pizza তে খাওয়া যাবেন। প্রতিটা team তার service নিজেই deploy করে।
Uber
Monolith থেকে migrate করেছেনে। Rider, Driver, Maps, Payment সব আলাদা service। Peak hour এ শুধু Matching service scale করে।
Spotify
Squads system — প্রতিটা Squad একটা service own করে। Search, Playlist, Social সব আলাদা। ৩০+ countries এ simultaneously deploy।
Tools Comparison
| Tool/Platform | Type | Best For | বাংলাদেশে ব্যবহার |
|---|---|---|---|
| Kubernetes (K8s) | Orchestration | Production microservices | Growing |
| Docker Compose | Local Dev | Development ও testing | Very Common |
| AWS ECS/EKS | Managed | Cloud deployment | Medium |
| Kong / NGINX | API Gateway | Request routing | Common |
| Kafka | Message Queue | Async communication | Growing |
| Jaeger / Zipkin | Tracing | Debugging distributed calls | Rare |
Common Interview Questions
Q1: Monolith vs Microservices কখন কোনটা choose করবেন?
Q2: Microservices এ inter-service communication কীভাবে হয়?
Asynchronous: Message Queue (Kafka, RabbitMQ)। Event-driven, decoupled। Payment notification, email পাঠানো এ ধরনের কাজে।
Q3: Service কতটা ছোট হওয়া উচিত?
Q4: Distributed system এ data consistency কীভাবে manage করুন?
SUMMARY — আজকে যা শিখলাম
| Concept | এক লাইনে |
|---|---|
| Microservices | বড় app কে ছোট independent services এ ভাগ করুন |
| API Gateway | Single entry point, routing, auth, rate limiting |
| DB per Service | প্রতিটা service এর নিজের DB — loose coupling |
| Sync Communication | REST/gRPC — real-time response দরকার হলে |
| Async Communication | Kafka/RabbitMQ — decoupled event-driven |
| CQRS | Read ও Write আলাদা করুন — performance boost |
| When to use | Large teams, complex domain, independent scaling দরকার হলে |