
Mikro hizmet mimarisi, bir uygulamayı gevşek bağlı, bağımsız olarak dağıtılabilen hizmetlerin bir koleksiyonu olarak yapılandırır. Her hizmetin belirli bir iş yeteneği vardır, kendi veri deposu vardır ve bir ağ üzerinden iletişim kurar. Mikro hizmetler önemli düzeyde operasyonel karmaşıklığa neden olurken kuruluşların geliştirme ekiplerini ölçeklendirmesine, bağımsız olarak dağıtım yapmasına ve daha dayanıklı sistemler oluşturmasına olanak tanır.
Mikro hizmet mimarisi, bir uygulamayı gevşek bağlı, bağımsız olarak dağıtılabilen hizmetlerin bir koleksiyonu olarak yapılandırır. Her hizmetin belirli bir iş yeteneği vardır, kendi veri deposu vardır ve bir ağ üzerinden iletişim kurar. Mikro hizmetler önemli düzeyde operasyonel karmaşıklığa neden olurken kuruluşların geliştirme ekiplerini ölçeklendirmesine, bağımsız olarak dağıtım yapmasına ve daha dayanıklı sistemler oluşturmasına olanak tanır.
Monolitik bir uygulama, tüm işlevselliğe tek bir kod tabanında ve dağıtım biriminde sahiptir:
┌─────────────────────────────────────────────┐
│ Monolith Application │
├──────────────┬──────────────┬───────────────┤
│ User Module │ Order Module│ Payment │
│ (controllers, services, repos, DB tables) │
└──────────────┴──────────────┴───────────────┘
Monolitin avantajları:
Monolitin dezavantajları:
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ User Service │ │ Order Service │ │ Payment Service │
│ (own DB, API) │ │ (own DB, API) │ │ (own DB, API) │
└────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘
│ │ │
└──────────────────────┼──────────────────────┘
│
┌───────────▼───────────┐
│ API Gateway │
│ (auth, routing) │
└───────────────────────┘
Her hizmet tam olarak bir iş yeteneğine sahiptir. Bir hizmetin amacını "ve" kullanmadan tanımlayabiliyorsanız, muhtemelen kapsamı iyi belirlenmiştir.
İyi:
payment-service — Ödeme işlemlerini ve geri ödemeleri yönetir.notification-service — E-posta, SMS ve anlık bildirimler gönderir.inventory-service — Stok seviyelerini ve rezervasyonları yönetir.Kötü:
backend-service — Her şey tek bir hizmette (mikro hizmetler değil).Her hizmetin kendi veri tabanı vardır. Hizmetler hiçbir zaman veritabanlarını paylaşmaz; API'ler aracılığıyla iletişim kurarlar.
-- Service A has its own database
CREATE TABLE users (
id UUID PRIMARY KEY,
email VARCHAR(255) UNIQUE,
name VARCHAR(255)
);
-- Service B has its own database, stores only the user ID
CREATE TABLE orders (
id UUID PRIMARY KEY,
user_id UUID NOT NULL,
total DECIMAL(10,2),
status VARCHAR(50)
);
Neden veritabanlarını paylaşmıyorsunuz?
Bir hizmetteki başarısızlık diğerlerine de yansımamalıdır.
Devre Kesici Modeli:
// Using a circuit breaker to handle service failures gracefully
const breaker = new CircuitBreaker({
failureThreshold: 5,
resetTimeout: 30000, // 30 seconds
});
async function getPaymentStatus(orderId: string) {
try {
return await breaker.call(() => paymentService.getStatus(orderId));
} catch (error) {
// Fallback: return cached status or default
return { status: 'pending', note: 'Payment service unavailable' };
}
}
Bölme Deseni: Yavaş bir hizmetin tüm kaynakları tüketmemesi için farklı hizmetler için ayrı iş parçacığı havuzları ayırın:
// Separate thread pools per service
const paymentPool = new ThreadPool({ maxThreads: 10 });
const inventoryPool = new ThreadPool({ maxThreads: 20 });
const notificationPool = new ThreadPool({ maxThreads: 5 });
Her hizmet bağımsız olarak dağıtılabilir. Bu, mikro hizmetlerin birincil faydasıdır.
Dağıtım otomasyonu:
# GitHub Actions for a single microservice
name: Deploy Payment Service
on:
push:
paths:
- 'services/payment/**'
- '.github/workflows/payment.yml'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: docker build -t payment-service .
- run: docker push registry.example.com/payment-service:${{ github.sha }}
- run: kubectl set image deployment/payment-service payment-service=registry.example.com/payment-service:${{ github.sha }}
Avantajları: Uygulaması ve gerekçesi basit. İstek-yanıt anlambilimi tanıdıktır.
Dezavantajları: Çalışma zamanı bağlantısı oluşturur — aşağı akış hizmeti kapalıysa arayan etkilenir.
// REST call using fetch
const order = await fetch(`http://order-service:8080/api/orders/${orderId}`);
// gRPC definition
service OrderService {
rpc GetOrder (GetOrderRequest) returns (Order);
}
message GetOrderRequest {
string order_id = 1;
}
Avantajları: Gevşek bağlantı, daha iyi dayanıklılık, olaya dayalı mimarileri destekler.
Dezavantajları: Nihai tutarlılık, hata ayıklamanın daha zor olması nedeniyle mesaj altyapısı gerektirir.
// Kafka producer
await producer.send({
topic: 'order.created',
messages: [{ value: JSON.stringify({ orderId, userId, total }) }]
});
// Kafka consumer in notification service
await consumer.run({
eachMessage: async ({ message }) => {
const { orderId, userId } = JSON.parse(message.value.toString());
await emailService.sendOrderConfirmation(userId, orderId);
}
});
| Kriterler | Senkron | Asenkron |
|---|---|---|
| Arayan kişinin anında yanıt alması gerekiyor mu? | Evet | HAYIR |
| Operasyon ertelenebilir mi? | HAYIR | Evet |
| Aşağı akış hizmeti her zaman mevcut mu? | Evet | Gerekli değil |
| Güçlü bir tutarlılığa mı ihtiyacınız var? | Evet | Sonunda sorun yok |
// Strangler Fig pattern
const gateway = express();
// Route to new service if available, fall back to monolith
gateway.use('/api/users', async (req, res, next) => {
try {
const response = await fetch('http://user-service/api/users' + req.path);
return res.json(await response.json());
} catch {
next(); // Fall through to monolith handler
}
});
| Hizmet Boyutu | Takım Boyutu | Dağıtım Sıklığı | Örnek |
|---|---|---|---|
| ⚡ Küçük | 1-3 geliştirici | Birden çok kez/gün | Kullanıcı doğrulama |
| 📐 Orta | 3-6 geliştirici | Günlük/haftalık | Sipariş işleme |
| 🏗️Büyük | 6-10 geliştirici | Haftalık | Ödeme platformu |
Temel kural: Bir hizmet, tek bir ekibin tamamına sahip olabileceği kadar küçük, anlamlı iş değeri sağlayacak kadar büyük olmalıdır.
Mikro hizmetler çok büyük miktarlarda telemetri üretir. Üç sütun:
1. Günlük kaydı:
// Structured logging (JSON)
{
"timestamp": "2026-05-24T10:30:00.123Z",
"level": "error",
"service": "payment-service",
"trace_id": "abc123",
"message": "Payment processing failed",
"error": "stripe: insufficient funds",
"metadata": { "order_id": "ord_456", "amount": 2999 }
}
2. Metrikler (Prometheus formatı):
# HELP http_requests_total Total HTTP requests
# TYPE http_requests_total counter
http_requests_total{method="POST",path="/api/payments",status="500"} 42
3. Dağıtılmış İzleme (Açık Telemetri):
# OpenTelemetry auto-instrumentation
OTEL_EXPORTER_OTLP_ENDPOINT: "http://otel-collector:4318"
OTEL_SERVICE_NAME: "payment-service"
OTEL_TRACES_SAMPLER: "parentbased_traceidratio"
OTEL_TRACES_SAMPLER_ARG: "0.1"
Dinamik ortamlarda (Kubernetes) IP adresleri değişir. Hizmetler birbirini DNS aracılığıyla bulur:
payment-service.namespace.svc.cluster.local.Tüm müşteri istekleri için tek bir giriş noktası:
| İşlev | Örnek |
|---|---|
| Yönlendirme | /api/users → kullanıcı hizmeti, /api/orders → sipariş hizmeti |
| Kimlik doğrulama | Yönlendirmeden önce JWT belirteçlerini doğrulayın |
| Hız sınırlaması | Müşteri başına 1000 talep/dakika |
| Dönüşüm iste | JSON'u Protobuf'a dönüştür |
| Yanıt önbelleğe alma | GET yanıtlarını önbelleğe al |
| Devre kesme | Sağlıksız hizmetlere yönlendirmeyi durdurun |
Tüm konfigürasyonu haricileştir:
# ConfigMap in Kubernetes
apiVersion: v1
kind: ConfigMap
metadata:
name: payment-service-config
data:
DATABASE_URL: "postgresql://..."
STRIPE_API_KEY: "${STRIPE_API_KEY}" # from Secret
MAX_RETRIES: "3"
FEATURE_FLAG_NEW_CHECKOUT: "true"
apiVersion: apps/v1
kind: Deployment
metadata:
name: payment-service
spec:
replicas: 3
selector:
matchLabels:
app: payment-service
template:
metadata:
labels:
app: payment-service
spec:
containers:
- name: payment-service
image: registry.example.com/payment-service:latest
ports:
- containerPort: 8080
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
Conway Yasası: Kuruluşlar, iletişim yapılarını yansıtan sistemler tasarlar. Ekibiniz hizmet sınırlarına göre organize edilmemişse mikro hizmetler sürtüşme yaratacaktır.
| Kategori | Seçenekler | Notlar |
|---|---|---|
| Çerçeve | Spring Boot, NestJS, FastAPI, Go kiti | Ekip uzmanlığına göre seçim yapın |
| API'si | REST, grPC, GraphQL | Dahili için gRPC, harici için REST |
| Mesajlaşma | Kafka, TavşanMQ, NATS | Yüksek verim için Kafka |
| Veritabanı | PostgreSQL, DynamoDB, MongoDB | Veritabanını hizmet ihtiyaçlarıyla eşleştirin |
| Konteyner | Liman işçisi | Evrensel |
| Orkestrasyon | Kubernet'ler | EKS, AKS, GKE veya kendi kendini yöneten |
| API Ağ Geçidi | Kong, Elçi, AWS API Ağ Geçidi | Hizmet ağı entegrasyonu elçisi |
| gözlemlenebilirlik | Açık Telemetri, Prometheus, Jaeger | OpenTelemetry standarttır |
| CI/CD | GitHub Eylemleri, GitLab CI, ArgoCD | GitOps için ArgoCD |
| Servis Ağı | Istio, Linkerd, Cilium | Basitlik için Linkerd |
| Gizli Yönetim | HashiCorp Vault, AWS Gizli Bilgileri Yöneticisi | Çoklu bulut için Vault |
Mikro hizmetler, bağımsız dağıtıma, ekip özerkliğine ve ölçeklenebilir sistemlere olanak tanıyan güçlü bir mimari modeldir. Ancak önemli bir operasyonel karmaşıklığa sahiptirler. En başarılı mikro hizmet benimsemeleri:
Mikro hizmetler varsayılan mimari değildir; belirli ölçeklendirme ve organizasyon sorunlarına yönelik bir çözümdür. Bunları varsayılan olarak değil bilinçli olarak seçin.
Henüz onaylı yorum yok. Yeni yanıtlar moderasyon bekleyebilir.