<

Feature Flag Altyapısı: Korkusuz Deploy'un Sessiz Kahramanı

Nisan ayında bir çarşamba günü, öğleden sonra çıktığımız sürüm, belirli bir sözleşme tipindeki müşterilerin fatura önizlemesini bozdu. Hata yalnızca 11 müşteriyi etkiliyordu ama içlerinden biri ay sonu faturalamasının tam ortasındaydı. Geri dönüş kararı verdik ve o an acı gerçekle yüzleştik: aynı sürümün içinde, üç haftadır beklenen iki büyük özellik daha vardı. Rollback, bozuk fatura önizlemesiyle birlikte o iki sağlam özelliği de geri aldı. Bir müşterinin sorununu çözerken altı yüz müşterinin yeni aldığı özellikleri ellerinden çektik. Deploy ile release'in aynı şey olmadığını, Wemosis'te CTO olarak ilk yılımın en pahalı dersi olarak o gün öğrendim.

Kod Yayında Ama Kapı Kapalı

Feature flag fikrinin özü tek cümle: kodun sunucuya çıkması ile kullanıcıya açılması ayrı olaylardır. Yeni özellik if bloğunun arkasında yayına çıkar, bayrak kapalıdır, kimse görmez. Açma kararı deploy'dan bağımsız, anlık ve geri alınabilir bir işlemdir. Nisan felaketi bu modelde şöyle biterdi: fatura önizleme bayrağını kapat, iki dakikada mesele bitti, öteki iki özellik yerinde durur. Rollback yok, acil sürüm yok, gece mesaisi yok.

Hazır servisleri inceledik; o dönem için hem bütçemize hem veri hassasiyetimize uymadı. İki haftalık işle kendi altyapımızı yazdık ve bilinçli olarak sıkıcı tuttuk: bayraklar veritabanında tek tablo; uygulama örnekleri bayrakları 30 saniyede bir çekip bellekte tutuyor; her bayrağın kapsamı ya tümü, ya belirli müşteri listesi, ya da yüzde dilimi. Yüzde dilimi için kullanıcı kimliği ile bayrak adının hash'i 0-99 arasına indirgeniyor. Bu determinizm kritik: aynı kullanıcı her istekte aynı dilime düşer, özellik bir görünüp bir kaybolmaz. İlk sürümde bunu bilmeden rastgele sayı kullanan bir arkadaşımız, sayfa her yenilendiğinde arayüzü değişen bir test kullanıcısıyla bunu kalıcı biçimde öğrendi.

Yüzde 5'in Kurtardığı Ay Sonu

Altyapının kendini amorti ettiği gün eylül başıydı. Rota optimizasyon motorunu yeniden yazmıştık; hesaplama sonuçları eskisinden farklı çıkabilen, riskli bir değişiklikti. Eski dünyada bu ya aylarca staging'de bekler ya da bir gece herkese birden açılırdı. Yeni dünyada önce yüzde 5'e açtık. Kırk sekiz saat içinde izleme panosunda tuhaflık belirdi: yüzde 5 diliminde ortalama rota süresi beklenenden kısa ama üç müşteride şikâyet — motor, gece yarısını geçen vardiyalarda molaları yanlış hesaplıyordu. Bayrağı o üç müşteri için kapattık, hatayı bir haftada düzelttik, dilimi 25-50-100 diye yürüttük. Aynı hata eski yöntemle 600 müşteriye aynı gece çarpacaktı. Kademeli açılım, hatayı yok etmiyor; hatanın patlama yarıçapını pazarlık edilebilir bir sayıya indiriyor.

Yüzde dilimini müşteri kimliği üzerinden mi kullanıcı kimliği üzerinden mi hesaplayacağınız da masum bir ayrıntı değil. Biz kurumsal bir ürün olduğumuz için müşteri kimliğini seçtik: bir şirketin iki çalışanının aynı ekranda farklı arayüz görmesi, destek hattı için kâbus olurdu. Tüketici ürünlerinde tercih genellikle tersine işler.

Kill switch tarafı da beklemediğimiz bir yerde işe yaradı. Harici SMS sağlayıcımız bir öğleden sonra yanıt sürelerini 30 kat şişirince, bildirim gönderimini saran bayrağı kapatıp kuyruğun boğulmasını önledik; sağlayıcı düzelince açtık. Bayraklar sadece yeni özellik kapısı değil, dış bağımlılıklara karşı devre kesici olarak da çalışıyor.

Altyapının performans ayağını da anlatayım, çünkü ilk tasarım taslağında klasik hatayı yapıyorduk: her bayrak kontrolünde veritabanına gitmek. Ortalama bir istek 6-8 bayrak kontrolünden geçiyor; istek başına 8 ek sorgu, sırf "bu özellik açık mı" diye. 30 saniyelik bellek önbelleği bu maliyeti pratikte sıfıra indirdi — kontrol, bellekteki bir map'te okuma. Bedeli ise yayılım gecikmesi: bayrağı kapattığınızda etkisi en geç 30 saniyede tamamlanıyor. Acil durumlar için bunu kısaltmak yerine dürüstçe kabullendik; kill switch'in 30 saniyesi, rollback'in 25 dakikası yanında hâlâ elli kat hızlı. Bir de değerlendirme loglaması ekledik: her istekte hangi bayrakların hangi değeri döndürdüğü, hata ayıklama kayıtlarına yazılıyor. "Müşteri X'te bu ekran neden farklı görünüyor" sorusunun cevabı artık tahmin değil, log satırı.

Bayrak Çöplüğüne Hoş Geldiniz

Altı ay sonra gurur tablosu utanç tablosuna dönmeye başladı: sistemde 43 bayrak vardı ve en az 15'i çoktan yüzde 100'e açılmış, bir daha asla kapanmayacak bayraklardı. Kodda her biri ölü bir if dalı olarak yaşıyor, test matrisini şişiriyor, yeni gelen geliştiriciye "bu bayrak kapalıyken ne oluyor" diye sorduran arkeolojik katmanlar oluşturuyordu. İki bayrağın etkileşimi yüzünden bir kez de gerçek bir hata yedik: A açık + B kapalı kombinasyonu hiçbir testte denenmemişti.

Çare olarak bayrağa doğum belgesi zorunluluğu getirdik: her bayrağın bir sahibi, bir amacı ve bir son kullanma tarihi tablodaki kaydında yazılı. Tarihi geçmiş bayraklar haftalık raporda sahiplerinin yüzüne okunuyor ve temizlik, sprint işi olarak planlanıyor. Bayrak sayımız o günden beri 20-25 bandında sabitlendi. Bayrak eklemek bir satır, yaşatmak ise faizli borç; bunu baştan bilseydik ilk günden yazardık bu kuralı.

Bir yıl içinde bayrakların beklenmedik bir kullanım alanı daha çıktı: operasyonel anahtarlar. Bakım moduna alma, raporlama modülünü salt-okunur yapma, ağır bir arka plan işini duraklatma gibi işlemler eskiden konfigürasyon değişikliği artı yeniden başlatma demekti; şimdi hepsi birer bayrak. Bu tür anahtarlar çoğalınca bir de denetim ihtiyacı doğdu: ekim ayındaki bir gece yarısı vakasında "bu bayrağı kim, ne zaman kapattı" sorusuna cevap verememek rahatsız ediciydi. Bayrak tablosuna değişiklik günlüğü ekledik; her açma-kapama, kim-ne zaman-eski değer-yeni değer dörtlüsüyle kayda giriyor. Üretim davranışını değiştiren her şey gibi bayraklar da izlenebilirlik ister; anlık gücün bedeli, kayıt disiplini.

Küçük Ekip İçin Ölçülü Reçete

Test stratejisi de bayraklarla birlikte evrildi. Kırk üç bayrağın bütün kombinasyonlarını test etmek kombinatorik olarak imkânsız; bunu kabul edip pragmatik bir sözleşme yaptık. CI'da test takımı iki profille koşuyor: bütün bayraklar üretimdeki hâliyle ve açılım sürecindeki bayraklar tam açık hâliyle. Ayrıca bir bayrağın iki tarafını da kapsayan en az bir test yazmak, bayrağı ekleyen geliştiricinin sorumluluğu. Bu, matematiksel bir garanti değil; ama nisan felaketinden bu yana bayrak kaynaklı tek üretim hatamız, o test sözleşmesinden önce eklenmiş yaşlı bir bayraktan geldi. Kusurlu ama işleyen bir sözleşme, kusursuz ama uygulanamayan bir matristen iyi.

Bir yılın muhasebesi net: rollback sayımız yılda 9'dan 1'e indi, riskli değişikliklerin üretime çıkma süresi kısaldı, "cuma günü deploy" tartışması anlamını yitirdi çünkü deploy'un kendisi olaysızlaştı. Bunun için ne bir SaaS sözleşmesi ne karmaşık bir platform gerekti; bir tablo, bir önbellek, deterministik bir hash ve — en zoru — bayrak hijyeni disiplini. Feature flag altyapısı, adı afili araçların değil, sıkıcı tutarlılığın işi. Kendi ekibiniz için benzer bir başlangıç reçetesi isterseniz iletişime geçin; iki haftalık o ilk sürümün şemasını çıkarır gönderirim.

📅 Yayınlanma:  ·  Yakup Zengin