Service Discovery & Registry
Service Discovery কেন শিখতে হবে?
আপনার microservices system এ Order Service কে Payment Service কে call করতে হবে। কিন্তু Payment Service এর IP কী? Kubernetes এ pods dynamically scale হয় — IP বদলায়। Hardcode করা impossible।
এই সমস্যার সমাধান হলো Service Discovery — services নিজেদের register করে, অন্যরা সেই registry থেকে খুঁজে নেয়।
DEFINITION
Service Discovery হলো একটা mechanism যেখানে services automatically তাদের network location (IP, port) একটা registry তে register করে। অন্য services ওই registry থেকে তাদের খুঁজে নেয়। Dynamic scaling এ IP hardcode করার দরকার নেই।
Without vs With Service Discovery
❌ Without Discovery
Order Service: http://192.168.1.45:8001/charge — hardcoded। Payment pod restart হলে IP বদলায় → app broken।
✅ With Discovery
Order Service: http://payment-service/charge — DNS name। Kubernetes DNS automatically resolve করে। Pod যেকোনো IP তে থাকুক।
দুটো Pattern — Client-side vs Server-side
1. Client-Side Discovery
Client নিজেই Service Registry থেকে service এর location বের করে এবং directly call করে। Netflix Eureka এই pattern follow করে।
CLIENT-SIDE DISCOVERY FLOW
2. Server-Side Discovery
Client একটা fixed endpoint এ request পাঠায়। Load Balancer / API Gateway নিজে Registry থেকে service location বের করে forward করে। Client কিছু জানে না। Kubernetes Service এই pattern।
SERVER-SIDE DISCOVERY (Kubernetes Style)
payment-svc (stable DNS)| Pattern | Load Balancing | Complexity | Example |
|---|---|---|---|
| Client-side | Client handles | Higher | Netflix Eureka + Ribbon |
| Server-side | LB/Infra handles | Lower | Kubernetes Service, AWS ALB |
Service Mesh — Infrastructure Layer
Service Discovery solve করার পরও বাকি থাকে: load balancing, circuit breaking, retry, mTLS, observability। প্রতিটা service এ আলাদাভাবে এগুলো implement করা tedious।
Service Mesh এই সমস্যা solve করে — প্রতিটা service এর পাশে একটা sidecar proxy বসায় (যেমন Envoy)। সব network traffic এই proxy দিয়ে যায়। Service কোড change করতে হয় না।
SERVICE MESH — SIDECAR PATTERN
POD A
Order
Service
Envoy
Sidecar
mTLS, LB
Circuit Breaker
POD B
Envoy
Sidecar
Payment
Service
mTLS Encrypted Channel
Mutual TLS · Auto cert rotation
Istio Control Plane
Service Mesh কী কী করে?
🔐 mTLS
Service-to-service communication automatically encrypted। Certificate management automatic। Zero-trust network।
⚖️ Load Balancing
Advanced algorithms: round-robin, least connections, consistent hashing। Health-aware routing।
⚡ Circuit Breaking
Code change ছাড়াই circuit breaker। YAML config এ define করুন। Language-agnostic।
📊 Observability
Automatic distributed tracing, metrics, logs। প্রতিটা service এ code লেখা লাগে না। Jaeger integration।
| Tool | Type | Proxy | Best For |
|---|---|---|---|
| Istio | Service Mesh | Envoy | Kubernetes — full featured, complex |
| Linkerd | Service Mesh | linkerd-proxy | Lightweight K8s mesh |
| Consul Connect | Mesh + Discovery | Envoy/built-in | Multi-platform, non-K8s too |
| AWS App Mesh | Managed Mesh | Envoy | AWS ECS/EKS |
| Consul | Discovery only | — | Multi-DC service registry |
| K8s DNS | Discovery only | — | Simple K8s service discovery |
Practical Code
Python: Consul Service Registration
# pip install python-consul
import consul
import socket
from fastapi import FastAPI
import uvicorn
import atexit
app = FastAPI()
c = consul.Consul(host='localhost', port=8500)
SERVICE_NAME = "payment-service"
SERVICE_PORT = 8001
SERVICE_ID = f"payment-service-{socket.gethostname()}"
def register_service():
"""Consul এ service register করুন"""
c.agent.service.register(
name=SERVICE_NAME,
service_id=SERVICE_ID,
address=socket.gethostbyname(socket.gethostname()),
port=SERVICE_PORT,
check={
"http": f"http://localhost:{SERVICE_PORT}/health",
"interval": "10s", # Every 10s health check
"timeout": "5s"
},
tags=["payment", "api", "v1"]
)
print(f"✅ Registered: {SERVICE_ID}")
def deregister_service():
"""Shutdown এ deregister করুন"""
c.agent.service.deregister(SERVICE_ID)
print(f"❌ Deregistered: {SERVICE_ID}")
def discover_service(service_name: str) -> str:
"""Service এর URL বের করুন"""
_, services = c.health.service(service_name, passing=True)
if not services:
raise Exception(f"No healthy instances of {service_name}")
# Simple round-robin (real এ load balancer করবেন)
service = services[0]['Service']
return f"http://{service['Address']}:{service['Port']}"
@app.on_event("startup")
async def startup():
register_service()
atexit.register(deregister_service)
@app.get("/health")
async def health():
return {"status": "healthy"}
@app.post("/orders")
async def create_order():
# Discover payment service dynamically
payment_url = discover_service("payment-service")
return {"payment_url": payment_url, "status": "processing"}Kubernetes: Service Discovery YAML
# Kubernetes Service — stable DNS endpoint
apiVersion: v1
kind: Service
metadata:
name: payment-service # DNS name হবে: payment-service.default.svc.cluster.local
namespace: default
spec:
selector:
app: payment # এই label এর pods কে route করবেন
ports:
- port: 80 # Service port
targetPort: 8001 # Pod এর actual port
type: ClusterIP # Internal only
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: payment-deployment
spec:
replicas: 3 # 3 pods — K8s Service load balances
selector:
matchLabels:
app: payment
template:
metadata:
labels:
app: payment
spec:
containers:
- name: payment
image: payment-service:latest
ports:
- containerPort: 8001
# Order service এখন শুধু "payment-service" use করে
# কোনো IP hardcode না!Real World Use Cases
☸️ Kubernetes DNS
সবচেয়ে common। K8s Service create করলেনই DNS entry হয়। payment-service.default.svc.cluster.local — automatic। কোনো external tool লাগে না।
🎬 Netflix Eureka
Client-side discovery। প্রতিটা service Eureka তে register করে। Ribbon load balancer client-side। Java Spring Cloud ecosystem।
🌐 Istio (Google)
K8s তে সবচেয়ে popular service mesh। Envoy sidecar। Traffic management, security, observability। Google, Lyft, IBM এর product।
🔗 Consul (HashiCorp)
K8s ছাড়াও কাজ করে। Multi-DC। VM এবং container উভয়ে। Health checking built-in। Terraform ecosystem এর সাথে ভালো।
Common Interview Questions
🎯 Q1: Service Discovery ছাড়া microservices কেন কাজ করে না?
Dynamic environment এ (K8s, auto-scaling) services এর IP constantly বদলায়। Hardcoded IP = broken system। Service Discovery: register on start, deregister on stop, discover by name। এটাই dynamic infrastructure এর foundation।
🎯 Q2: Service Mesh কি সবসময় দরকার?
না। Small microservices (৫-১০ services), simple communication — Service Mesh overkill। K8s DNS যথেষ্ট। ৫০+ services, complex traffic policies, zero-trust security, observability দরকার হলে Service Mesh consider করুন।
🎯 Q3: Sidecar Pattern কীভাবে কাজ করে?
প্রতিটা service pod এ দুটো container: (1) actual service, (2) Envoy proxy sidecar। সব inbound/outbound traffic proxy দিয়ে যায়। Service কোড change ছাড়াই mTLS, retry, circuit breaking পানয়া যায়। Control Plane (Istiod) সব sidecars কে configure করে।
Interview এ এটা বলুন
Health Check — কেন গুরুত্বপূর্ণ?
Service crash হলে registry থেকে remove হওয়া দরকার। Regular health checks (HTTP /health endpoint, TCP check) দিয়ে Consul/K8s automatically unhealthy pods কে deregister করে। Traffic only healthy instances এ যায়।
Health Check ছাড়া Service Discovery অসম্পূর্ণ
Service crash হলে যদি registry তে এখনও registered থাকে, অন্য services সেই dead instance এ traffic পাঠাবে — errors হবে। Health Check ছাড়া Service Discovery কাজ করে না properly।
Proper Health Check Endpoint Design
from fastapi import FastAPI, Response
import httpx
import asyncpg
app = FastAPI()
@app.get("/health")
async def health_check(response: Response):
"""
Proper health check — সব dependencies check করুন
"""
checks = {
"status": "healthy",
"database": "unknown",
"external_api": "unknown"
}
# Database connection check
try:
conn = await asyncpg.connect("postgresql://localhost/mydb")
await conn.execute("SELECT 1")
await conn.close()
checks["database"] = "healthy"
except Exception as e:
checks["database"] = f"unhealthy: {str(e)}"
checks["status"] = "unhealthy"
# External service check
try:
async with httpx.AsyncClient(timeout=2.0) as client:
resp = await client.get("https://external-api/ping")
if resp.status_code == 200:
checks["external_api"] = "healthy"
else:
checks["external_api"] = "degraded"
except Exception:
checks["external_api"] = "unhealthy"
# External service unhealthy কিন্তু আমরা still serve করতে পারবো
# তাই status "degraded" — critical না হলে
if checks["status"] == "unhealthy":
response.status_code = 503 # Service Unavailable
return checks
# Consul এ register করার সময় এই endpoint দিন:
# "http": "http://localhost:8001/health"
# Consul 503 response দেখলে automatically deregister করবেনকোন Tool কখন ব্যবহার করবো?
Service Discovery এর জন্য অনেক tool আছে। কোনটা কখন ব্যবহার করবেন সেটা জানা important।
| Scenario | Recommended Tool | কারণ |
|---|---|---|
| Kubernetes only environment | K8s DNS (built-in) | No extra setup, automatic, free |
| K8s + complex traffic management | Istio | mTLS, circuit breaking, observability |
| K8s + lightweight mesh | Linkerd | Simpler than Istio, less overhead |
| Mixed (VMs + containers) | Consul | Works everywhere, multi-DC support |
| AWS managed environment | AWS App Mesh | Managed, ECS/EKS integration |
| Java Spring Cloud apps | Netflix Eureka + Ribbon | Spring ecosystem integration |
Decision Framework
SUMMARY — আজকে যা শিখলাম
| Concept | এক লাইনে |
|---|---|
| Service Discovery | Services নিজেদের register করে, অন্যরা name দিয়ে খোঁজে |
| Client-Side | Client নিজে LB করে — Netflix Eureka+Ribbon |
| Server-Side | LB/Infra করে — K8s Service, AWS ALB |
| K8s DNS | Simplest — Service create করলেনই DNS auto |
| Service Mesh | Sidecar proxy — mTLS, LB, CB, tracing auto |
| Envoy | Industry standard proxy — Istio, Consul, AWS এ |
| Health Check | Unhealthy service automatically deregister হয় |