# 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://www.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.

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.

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 — sadece akışı durdurun.
2. **Go'da `server.Shutdown(ctx)` kullanın.** `signal.NotifyContext` ile SIGTERM'i yakalayın, `http.Server`'a deadline'lı bir context verin: `server.Shutdown(ctx)`. Bu yeni bağlantıları reddeder, açık istekleri timeout'a kadar bitirir. `ListenAndServe`'i `kill -9` ile değil bu yolla sonlandırın.
3. **Octane'de graceful stop/reload kullanın.** Octane sürecini `octane:stop`/graceful reload ile indirin; 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 "öldürmeden önce kaç saniye bekleyeceğini" en uzun kabul edilebilir drain süresine eşitleyin. Aksi halde platform SIGTERM'den sonra SIGKILL atıp drain'i yarıda keser.
5. **Uzun job'ları idempotent/resumable yapın.** Grace süresi yetmez ve süreç sert kapanırsa bile güvende olmak için uzun işleri tekrar çalıştırılabilir tasarlayı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. Octane'in kalıcı süreç modelinin bu kapanış davranışını neden değiştirdiğini hub'daki yazıda daha ayrıntılı anlattım.

## İlgili Yazılar

- [Laravel Octane: kalıcı süreçle gelen performans](/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://www.muhammetsafak.com.tr/sor-bakalim/go-da-gc-baskisini-sync-pool-ve-escape-analizi-ile-azaltmak/) — Sor Bakalım
- [Birbirine bağımlı birden fazla işi, ilk hata hepsini iptal edecek şekilde errgroup ile mi yürütmeliyim?](https://www.muhammetsafak.com.tr/sor-bakalim/birbirine-bagimli-birden-fazla-isi-ilk-hata-hepsini-iptal-edecek-sekilde/) — Sor Bakalım
- [İşlediğim satırları aynı anda güncellerken chunk yerine chunkById mı kullanmalıyım?](https://www.muhammetsafak.com.tr/sor-bakalim/isledigim-satirlari-ayni-anda-guncellerken-chunk-yerine-chunkbyid-mi-kullanmaliyim/) — Sor Bakalım
