Bu teknik makale; saniyede 15.000+ anlık OTP isteği üreten yüksek trafikli platformlarda Kubernetes Horizontal Pod Autoscaler (HPA v2), Multi-stage Dockerfile optimizasyonu ve EnOnay REST API Gateway v1.4 entegrasyonuyla zero-downtime kimlik doğrulama mimarisinin nasıl inşa edildiğini adım adım ele almaktadır.
1. Mikroservis Mimarilerinde SMS OTP Ölçekleme Problemleri
Monolitik sistemlerden mikroservis ve container tabanlı kümelere (Kubernetes) geçiş yapan mühendislik ekiplerinin karşılaştığı en kritik darboğazlardan biri, anlık kampanya ve flaş indirim (flash sales) dönemlerinde ortaya çıkan OTP kuyruk tıkanması (Queue Starvation) ve Pod Eviction sorunlarıdır. Kullanıcı oturum açma, kayıt veya ödeme onayı esnasında SMS gönderim çağrıları senkron (blocking HTTP call) olarak yapıldığında:
- Thread Havuzunun Tükenmesi: Dış telekom ağındaki 200-800ms gecikmeler uygulama worker thread'lerini kilitler ve Ingress 504 Gateway Timeout hatalarına yol açar.
- Kaynak Sızıntısı ve OOMKilled: Bellek yönetimi optimize edilmemiş hantal Docker imajları (Node.js veya Python tabanlı 1GB+ container'lar) cluster nodeları üzerinde Out-Of-Memory (OOM) kaynaklı pod çökmelerine sebep olur.
- Throttling ve Hatalı Ölçeklenme: Sadece CPU ve Bellek kullanımına dayalı HPA kuralları, harici ağ gecikmesi esnasında CPU idle kaldığı için pod sayısını artıramaz; kuyrukta on binlerce SMS birikir.
2. Kubernetes & Worker Havuzu Dağıtık Sistem Mimarisi
Bu darboğazları bertaraf etmek için Event-Driven Architecture (EDA) modeli benimsenir. API pod'ları gelen istekleri derhal karşılayarak benzersiz bir order_id üretir ve RabbitMQ / Redis Streams kuyruğuna aktarır. Asenkron Kubernetes Worker Pod'ları ise EnOnay REST API üzerinden SMS teslimatını gerçekleştirir.
+-------------------------------------------------------------------------------+
| KUBERNETES SMS VERIFICATION & HPA MİMARİSİ |
+-------------------------------------------------------------------------------+
| |
| [ Ingress Controller / NGINX ] ---> TLS Termination / Rate Limiting |
| | |
| v |
| [ SMS Gateway REST API Pods ] (Deployment: 3..15 Pods via CPU/RPS HPA) |
| | |
| v |
| [ RabbitMQ / Redis Cluster ] <== Asenkron SMS Dağıtım Kuyrukları (Queue) |
| | |
| v |
| +-----------------------------------------------------------------------+ |
| | K8s Worker Pods (HPA: sms_queue_depth custom metrics ile ölçeklenir) | |
| | +--------------+ +--------------+ +--------------+ | |
| | | Worker Pod 1 | | Worker Pod 2 | | Worker Pod N | (Max: 50 Pods) | |
| | +-------+------+ +-------+------+ +-------+------+ | |
| +----------|-----------------|-----------------|------------------------+ |
| +-----------------+-----------------+ |
| | |
| v (mTLS, Egress Gateway, Secret Enjeksiyonu) |
| [ EnOnay Global SMS API Gateway v1.4 (HTTPS) ] |
| | |
| v |
| [ 180+ Global Telekom Operatörü / GSM ] |
+-------------------------------------------------------------------------------+
3. Multi-Stage Dockerfile Optimizasyonu (14MB Minimal Image)
Docker container boyutunu küçültmek, pod başlatma süresini (cold start) saniyelerden milisaniyelere düşürür. Bu durum Kubernetes kümesinde ani yük dalgalanmalarında yeni pod'ların derhal devreye girmesi için hayati önem taşır.
Aşağıdaki çok aşamalı (multi-stage) Dockerfile örneği, Go tabanlı bir SMS onay worker servisini distroless/static taban imajına derleyerek güvenli ve son derece hafif bir container üretir:
# --- Aşama 1: Derleyici (Builder) ---
FROM golang:1.22-alpine AS builder
WORKDIR /src
RUN apk add --no-cache ca-certificates git tzdata
# Bağımlılık katmanını önbelleğe al
COPY go.mod go.sum ./
RUN go mod download
# Uygulama kaynak kodunu derle
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w -extldflags '-static'" -o /bin/enonay-sms-worker ./cmd/worker
# --- Aşama 2: Minimal Çalışma Zamanı (Scratch / Distroless) ---
FROM gcr.io/distroless/static:nonroot
LABEL maintainer="En Onay Mühendislik Ekibi <[email protected]>"
LABEL service="sms-otp-worker"
WORKDIR /app
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /bin/enonay-sms-worker /app/enonay-sms-worker
# Non-root güvenlik kullanıcı kimliği (65532:nonroot)
USER 65532:65532
ENTRYPOINT ["/app/enonay-sms-worker"]
4. Kubernetes Deployment, ConfigMap ve Secret Manifestoları
EnOnay API anahtarını güvenli şekilde inject etmek için Kubernetes Secret ve HashiCorp Vault / SealedSecrets entegrasyonu kullanılır. Pod'ların kontrollü şekilde kapanabilmesi için terminationGracePeriodSeconds ve pod koruma mekanizması (PDB) eklenir:
apiVersion: apps/v1
kind: Deployment
metadata:
name: enonay-sms-worker
namespace: identity-services
labels:
app: enonay-sms-worker
tier: background-worker
spec:
replicas: 3
selector:
matchLabels:
app: enonay-sms-worker
template:
metadata:
labels:
app: enonay-sms-worker
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
prometheus.io/path: "/metrics"
spec:
terminationGracePeriodSeconds: 45
securityContext:
runAsNonRoot: true
runAsUser: 65532
fsGroup: 65532
containers:
- name: worker
image: registry.kurumsal.com/identity/enonay-sms-worker:v1.4.2
imagePullPolicy: IfNotPresent
env:
- name: ENONAY_API_BASE_URL
value: "https://enonay.com/api/v1.php"
- name: ENONAY_API_KEY
valueFrom:
secretKeyRef:
name: enonay-credentials
key: api-token
- name: RABBITMQ_URL
valueFrom:
secretKeyRef:
name: queue-credentials
key: amqp-uri
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 3
periodSeconds: 5
5. Custom Metrics HPA ile Dinamik Pod Ölçekleme (RabbitMQ Queue Depth)
CPU bazlı ölçekleme SMS işleme kuyruklarında yetersiz kalır. Çünkü 10.000 SMS kuyrukta beklerken worker pod'ları I/O beklediği için CPU %25'i geçmeyebilir.
Bu sebeple Prometheus Adapter kullanarak rabbitmq_queue_messages_ready metriği üzerinden HPA v2 kuralı tanımlanır:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: enonay-sms-worker-hpa
namespace: identity-services
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: enonay-sms-worker
minReplicas: 3
maxReplicas: 35
metrics:
- type: External
external:
metric:
name: rabbitmq_queue_messages_ready
selector:
matchLabels:
queue: sms_otp_high_priority
target:
type: AverageValue
averageValue: "50"
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 75
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 20
periodSeconds: 60
6. Performans Analizi & Benchmark Tablosu
Aşağıdaki veriler, Kubernetes kümesi üzerinde yürütülen 50.000 eş zamanlı OTP doğrulama testinin sonuçlarını göstermektedir:
| Mimari / Konfigürasyon | P95 Gecikme | Max Eş Zamanlı RPS | Container Bellek İzi | Kuyruk Boşaltma Süresi |
|---|---|---|---|---|
| Monolitik Senkron SMS Çağrısı | 1.850 ms | 650 RPS | ~850 MB | Tıkanma / Hata |
| Standart K8s (Yalnızca CPU HPA) | 480 ms | 3.200 RPS | ~250 MB | 4 dk 20 sn |
| EnOnay + Queue HPA + Distroless (Önerilen) | 85 ms | 14.500+ RPS | 14.2 MB | 18 saniye |
7. Graceful Termination & SIGTERM İşleme Mantığı
Kubernetes bir pod'u küçültürken (scale-down) veya node tahliyesi (eviction) yaparken pod'a SIGTERM sinyali gönderir. Worker o sırada EnOnay API üzerinden bir SMS işliyorsa bu işlem yarım kalmamalıdır. Go dilinde sinyal yakalama mekanizması:
func (w *Worker) Start(ctx context.Context) {
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-sigChan
log.Println("SIGTERM alındı! Yeni kuyruk mesajı alımı durduruluyor...")
w.consumer.Stop() // AMQP consumer durdurulur
// Halihazırda işlemde olan SMS çağrılarının tamamlanması beklenir
w.wg.Wait()
log.Println("Tüm aktif SMS doğrulama çağrıları tamamlandı. Pod güvenle kapanıyor.")
w.doneChan <- struct{}{}
}()
}
8. Sık Sorulan Sorular (Kubernetes SMS Ölçekleme FAQ)
EnOnay API çağrılarında egress gateway IP'sini sabitlemek gerekir mi?
Evet. Kurumsal güvenlik ve IP whitelist kural seti için Kubernetes kümenizin giden (egress) trafiğini statik bir Cloud NAT veya Egress Gateway üzerinden yönlendirerek EnOnay panelinizde bu IP'leri yetkilendirebilirsiniz.
Geniş ölçekli yük testleri için test numaraları tahsis edilebilir mi?
Elbette. Canlı test senaryolarında üretim bakiyenizi tüketmemek ve sürekli test yapabilmek için özel kiralık numaralar veya sandbox API anahtarlarını kullanabilirsiniz.