Ana sayfa → Teknik
Canlıya Çıkmak: Deploy Değil, Sürüm Yönetimi
Cuma 15:40, yeni ödeme akışı canlıda. 15:58’de hata oranı %0,4’ten %6’ya çıktı. Geri alma başlattık; 9 dakika sürdü. O 9 dakikada 1.100 kullanıcı ödeme ekranında takıldı. Aynı değişiklik bir flag’in arkasında olsaydı kapatması 4 saniye sürecekti. Flag yoktu.
- Deploy ile sürüm aynı şey değil. Deploy kodu sunucuya koyar, sürüm kullanıcıya gösterir. Aynı anda olmaları tesadüf olmalı, kural değil.
- Geri alma süren, en yavaş geri alma yolun kadardır. Deploy’u geri almak dakikalar, flag kapatmak saniyeler sürer.
- Dört ayrı flag tipi var, ömürleri farklı. Hepsini tek torbaya atarsan hiçbirini silemezsin.
- Flag mezarlığı gerçek bir borç. 61 flag’imiz vardı, 23’ü bir yıldan eskiydi; ikisi birbiriyle çelişiyordu.
- Silme tarihi flag açılırken yazılır. Sonradan temizlik kampanyası yapmak işe yaramıyor; CI’ın uyarması gerekiyor.
- Kademeli çıkışın eşiği insana bırakılmaz. İnsana bırakılan eşik, gece 03:00’te çalışmayan eşiktir.
Sahadan: 9 dakika ile 4 saniye
O cuma yaptığımız şey teknik olarak doğruydu: hata fark edildi, karar verildi, sürüm geri alındı, sistem düzeldi. Kimse panik yapmadı. Yine de 9 dakika kaybettik ve bu 9 dakikanın tamamı kaçınılabilirdi.
Sebep şu: değişikliği canlıya çıkarmanın tek yolu deploy’du, dolayısıyla geri almanın da tek yolu deploy’du. Deploy bir yapı işidir — imaj çekilir, pod’lar değişir, sağlık kontrolleri beklenir. Hızlandırabilirsin ama saniyeye indiremezsin. Oysa “bu özelliği kullanıcıya gösterme” kararı bir okuma işidir; bir değerin okunmasıdır ve saniyeler sürer.
Ertesi hafta aynı akışı flag arkasında yeniden çıkardık. Üç gün kapalı kaldı, sonra %5 kullanıcıya açtık. İkinci günün sabahında aynı hata sınıfı tekrar göründü — bu sefer kapatmak bir alan değişikliğiydi, etkilenen kullanıcı sayısı 40 civarıydı. Aynı hata, iki farklı maliyet.
Deploy ≠ sürüm
| Deploy | Sürüm | |
|---|---|---|
| Ne yapar | Kodu sunucuya koyar | Kullanıcıya gösterir |
| Kim karar verir | Mühendis / pipeline | Ürün + mühendis birlikte |
| Ne kadar sürer | Dakikalar | Saniyeler |
| Geri alma | Yeni deploy | Bir değeri değiştirmek |
| Riski | Teknik (çalışıyor mu?) | Ürün (doğru şey mi?) |
| Ne sıklıkta | Günde birçok kez | Hazır olduğunda |
Bu ayrımın en sevdiğim yan etkisi şu: ikisi ayrıldığında “bu iş yetişmeyecek, sürümü kaydıralım” tartışması bitiyor. Kod çıkar, kapalı durur, hazır olduğunda açılır. Yarım kalan işi bir dalda bekletmek zorunda kalmıyorsun — ki bekleyen dal, birleşirken en çok çatışan daldır.
Not: deploy’u sıklaştırmanın neden bu kadar önemli olduğunu ve deploy treninin ekipleri nasıl kilitlediğini monolitten mikroservise yazısında anlatmıştım; burada tekrar etmiyorum.
Dört flag tipi, dört ömür
“Feature flag” tek bir şey değil. Hepsini aynı listede tutmak, silme kuralını imkânsızlaştırıyor — çünkü biri “ama bazıları kalıcı” deyince bütün temizlik duruyor. Dört tip ve beklenen ömürleri:
1) SURUM FLAG'I : yeni ozelligi kademeli acmak
omur: gunler-haftalar --> acildiktan sonra SILINIR
2) KILL SWITCH : bir ozelligi acil kapatma kolu
omur: kalici --> silinmez, ama YILDA BIR test edilir
3) DENEY (A/B) : iki varyanti karsilastirmak
omur: deney suresi --> sonuc cikinca SILINIR
4) IZIN / SEGMENT : "bu musteri bu ozelligi kullanabilir"
omur: kalici --> aslinda flag degil, yetkilendirme;
flag sisteminde durmamali
Dördüncü tip bizde en çok karışan yerdi. “Kurumsal müşteriler şu ekranı görebilir” bir sürüm kararı değil, bir yetkilendirme kuralı. Flag sisteminde tuttuğun sürece hem silinemiyor hem de flag sayısını şişiriyor. Ayırdığımızda 61 flag’in 14’ü tek hamlede listeden çıktı.
Flag mezarlığı ve silme kuralı
Flag açmak bir kişinin beş dakikasını alıyor; silmek ise kimsenin işi değil. Sonuç tahmin edilebilir: bizde 61 aktif flag vardı, 23’ü bir yıldan eskiydi. İkisi birbiriyle çelişiyordu — biri yeni akışı açıyor, diğeri eski akışı zorluyordu; hangi kullanıcının hangisini gördüğü kodu okumadan bilinmiyordu.
Temizlik kampanyası denedik, işe yaramadı. İşe yarayan şey, kararı flag’i açarken almaktı:
- Çeyrek sonu “flag temizliği” sprint’i
- Wiki’de flag envanteri tutmak
- “Sahibi kim?” diye etiket eklemek
Üçü de hatırlamaya dayanıyor. Hatırlamaya dayanan hiçbir kural üç ay yaşamıyor.
- Flag tanımında zorunlu
silme_tarihialanı - Tarihi geçince CI uyarı üretir
- İki hafta sonra CI derlemeyi kırar
- Kalıcı tipler (kill switch, izin) kuraldan muaf, ayrı işaretli
Karar, flag açılırken ve bir satırda veriliyor. Kimsenin hatırlaması gerekmiyor.
Sert gelebilir ama derlemeyi kırma kısmı şart. Sadece uyarı verdiğimiz iki ay boyunca hiçbir flag silinmedi; uyarılar listenin dibine düştü. Kırmaya başladığı hafta 18 flag temizlendi.
Kademeli çıkış: eşiği önceden yaz
Kademeli çıkışı “önce az kullanıcıya açalım, bakarız” diye yapmak, yapmamakla neredeyse aynı. “Bakarız” kimin bakacağını, ne kadar bakacağını ve neye bakacağını söylemiyor. Adımları yazılı hâle getirdik:
ADIM TRAFIK EN AZ SURE OTOMATIK GERI ALMA ESIGI
-----------------------------------------------------------
1 %1 15 dakika hata orani > %1 VEYA p95 > 800ms
2 %5 30 dakika hata orani > %1 VEYA p95 > 800ms
3 %25 2 saat ayni
4 %100 - ayni (24 saat izlenir)
KURAL: esik asilirsa otomatik geri alinir, kimse onay vermez.
Gece 03:00'te insana sorulan esik, calismayan esiktir.
KURAL: bir adim atlanamaz; "acelesi var" diyen adimi atlatamaz,
adimlarin suresini kisaltabilir ve bunu yaziyla yapar.
İki ayrıntı önemli. Birincisi en az süre: yüzdeyi artırmak için “sorun görünmüyor” yetmiyor, en az o kadar beklemek gerekiyor. Çoğu sorun trafikle değil, zamanla ortaya çıkıyor — bellek sızıntısı, dolan bir kuyruk, birikmiş bir tablo. İkincisi otomatiklik: eşiği insana bırakırsan, eşik yalnızca birinin uyanık olduğu saatlerde çalışır.
Nöbetçinin gece bir flag’i tek başına kapatabilmesi de bu düzenin parçası; nöbet yazısında “geri alınabilir işler gece serbesttir” derken kastettiğim şeylerden biri bu.
Ne izlemeli?
| Ne | Neden | Bizde ne oldu |
|---|---|---|
| Geri alma süresi (en yavaş yol) | Gerçek risk bu; ortalama değil, en kötü yol ölçülür | 9 dk → flag’li akışlarda saniyeler |
| Sürümlerin kaçı flag arkasında | Düşükse her hata bir deploy geri alması demek | Hedef: kullanıcıya görünen her değişiklik |
| Açık flag sayısı ve en eskisinin yaşı | Yaş, borcun faizi; sayı tek başına yanıltıcı | 61 flag / en eski 14 ay → 30 / 3 ay |
| Kademeli çıkışta yakalanan hata oranı | %100’e gitmeden yakalananlar, sistemin kazandığı tek şey | Yakalanmayan her hata bir plan boşluğu |
Bende işe yaramayanlar
- Flag’i kod içinde
ifile dağıtmak. Başta pratik geldi. Altı ay sonra aynı flag yedi yerde okunuyordu ve biri eski varsayılanı kullanıyordu. Flag okuma tek bir yerden geçmeli; dallanma değil, kararın kendisi merkezî olmalı. - “Önemli değişikliklerde kademeli çıkarız.” “Önemli”yi kim belirliyor? Kimse. Sonuçta en sessiz görünen değişiklik — bir yapılandırma satırı — en büyük kesintiyi yaptı. Şimdi kural tersine: kullanıcıya görünen her şey kademeli çıkar, istisna yazıyla istenir.
- Mavi-yeşil (blue-green) ile işi bitirmiş sanmak. Trafiği anında çevirmek güzel ama ya hep ya hiç. %1’lik bir dilime çıkamıyorsan, hatayı bütün kullanıcılarda keşfediyorsun demektir. İkisi birbirinin alternatifi değil; mavi-yeşil altyapı, kademeli çıkış karar katmanı.
Kontrol listesi
- Bu değişikliği geri almanın en hızlı yolu ne, kaç saniye sürüyor?
- Kullanıcıya görünen kısım bir flag’in arkasında mı?
- Flag’in tipi ve silme tarihi yazılı mı?
- Kademeli çıkış adımları, süreleri ve eşikleri önceden belli mi?
- Eşik aşılınca geri alma otomatik mi, yoksa birinin onayını mı bekliyor?
- Nöbetçi bu flag’i gece tek başına kapatabilir mi?
- Veri tarafı geriye dönük uyumlu mu — eski ve yeni sürüm bir süre yan yana çalışacak?
- Şu an kaç açık flag var, en eskisi kaç aylık?
Sonuç
O cuma sorun yeni ödeme akışının hatalı olması değildi; her akış bir gün hatalı olur. Sorun, hatayı geri almanın tek yolunun sunucu beklemek olmasıydı. Kodu çıkarmakla kullanıcıya göstermeyi aynı ana bağlamıştık, o yüzden ürün kararını geri almak için bir yapı işlemi çalıştırmak zorunda kaldık.
Sürüm yönetimi, hata yapmamak için değil, hatanın maliyetini seçebilmek için var. Aynı hata 1.100 kullanıcıya da çıkabiliyor 40 kullanıcıya da; farkı yaratan kodun kalitesi değil, çıkış düzeni.
Tek soruyla ölç: şu an canlıdaki en son değişikliği geri almak kaç saniye sürer? Cevap dakikaysa, sürüm yönetimin yok; deploy’un var.