# Autoscaling scale-in sırasında SIGTERM ile graceful shutdown'ı nasıl sağlarım?

> SIGTERM'de önce load balancer'dan çıkıp yeni isteği kesin, açık işleri server.Shutdown(ctx) deadline'ında bitirin ve grace süresini drain'e hizalayın.

- Soruldu: 2026-05-18
- Yanıtlandı: 2026-05-21
- Soran: Ozan
- Etiketler: performans, olcekleme, go
- Kaynak: https://muhammetsafak.com/tr/sor-bakalim/autoscaling-sirasinda-sigterm-ile-graceful-shutdown/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
**Soru:** AWS'te CPU %70'i geçince Autoscaling yeni EC2 açıyor, %30'un altına düşünce bazılarını kapatıyor (scale-in). Sunucu kapanırken içeride işlenen uzun HTTP istekleri veya kuyruk job'ları yarıda kesiliyor ve tutarsızlık oluşuyor.

Uygulamanın (Laravel Octane / Go) `SIGTERM`'i yakalayıp mevcut istekleri bitirerek ve yeni istek almayarak zarifçe kapanmasını nasıl sağlarım?


Kısa cevap: Scale-in işleri yarıda kesiyor çünkü uygulama `SIGTERM`'de drain etmiyor — sürecin kapanış yaşam döngüsünü düzeltmeniz gerekiyor.

## Kısa cevap

Asıl mesele autoscaling değil, kapanış protokolü: platform SIGTERM gönderdiğinde uygulamanız ya hemen ölüyor ya da işini bitirmeden kesiliyor. Doğru sıra şu: önce trafiği kesin, sonra mevcut işi bitirin, en son ölün. Kalıcı süreç modelinin bu davranışı neden değiştirdiğini [Laravel Octane yazısında](/tr/blog/laravel-octane-kalici-surecle-gelen-performans/) anlatmıştım.

## Neden

1. **Kapanış bir protokoldür, bir olay değil.** "Öl" sinyali geldiğinde yapılacak üç iş var ve sırası önemli; ikisini atlayıp doğrudan üçüncüye giderseniz veri bozulur.

2. **Platformun sabrı sınırlı.** SIGTERM'den sonra grace süresi dolunca SIGKILL gelir; drain süreniz o pencereden uzunsa iş yine yarıda kesilir.

3. **Hiçbir drain penceresi %100 garanti değildir.** Süreç sert kapanabilir; bu yüzden son savunma kodun kendisinde olmalı.

## Ne yapmalı

1. **SIGTERM'i yakalayın ve yeni istek almayı durdurun.** İlk hamle readiness probe'unu fail ettirmek veya kendinizi load balancer'dan **deregister** etmek; böylece LB size yeni istek yönlendirmeyi keser. Mevcut bağlantıları henüz kapatmayın.

2. **Go'da `server.Shutdown(ctx)` kullanın.** `signal.NotifyContext` ile SIGTERM'i yakalayın, `http.Server`'a deadline'lı bir context verin. Bu yeni bağlantıları reddeder, açık istekleri timeout'a kadar bitirir.

3. **Octane'de graceful stop/reload kullanın.** Worker'lar mevcut isteği bitirip yenisini almaz. Kuyruk tarafında `queue:work`, `kill -9` atmadığınız sürece SIGTERM'i kendisi ele alır — çalışan job'ı bitirir, yeni job claim etmez.

4. **Platformun grace süresini drain'inizle hizalayın.** ASG'de lifecycle hook, k8s'te `terminationGracePeriodSeconds` ile platformun bekleme süresini en uzun kabul edilebilir drain süresine eşitleyin.

5. **Uzun job'ları idempotent/resumable yapın.** Her adım idempotent olsun, yarıda kalan job baştan veya kaldığı yerden güvenle dönsün.

**Sonuç:** Sıra önemli: önce LB'yi drain edin, sonra yeni istek alımını kesin, sonra mevcut işi bitirin, en son ölün. Go'da bunu `server.Shutdown(ctx)`, Octane'de graceful reload + `queue:work`'ün doğal SIGTERM davranışı verir; platform tarafında grace süresini gerçek drain süresine hizalayın. Üstüne job'ları idempotent yaparsanız sert kill bile veriyi bozmaz.

## İlgili Yazılar

- [Laravel Octane: kalıcı süreçle gelen performans](/tr/blog/laravel-octane-kalici-surecle-gelen-performans/) — Blog
- [Go'da GC baskısını sync.Pool ve escape analizi ile nasıl azaltırım?](https://muhammetsafak.com/tr/sor-bakalim/go-da-gc-baskisini-sync-pool-ve-escape-analizi-ile-azaltmak/) — Sor Bakalım
- [Kanal tampon boyutu seçimi backpressure sorunlarını gizler mi, nasıl karar vermeliyim?](https://muhammetsafak.com/tr/sor-bakalim/kanal-tampon-boyutu-backpressure-sorunlarini-gizler-karar-vermeliyim/) — Sor Bakalım
- [Container'daki Go worker'ım SIGTERM almıyor ve graceful kapanmıyor, bu bir PID 1 sorunu mu?](https://muhammetsafak.com/tr/sor-bakalim/containerdaki-go-workerim-sigterm-almiyor-pid-1-sorunu/) — Sor Bakalım
