paint-brush
Değişiklikler Güvenli Bir Şekilde Üretime Nasıl Gönderilir?ile@israel_hlc
16,506 okumalar
16,506 okumalar

Değişiklikler Güvenli Bir Şekilde Üretime Nasıl Gönderilir?

ile 10m2023/10/24
Read on Terminal Reader

Çok uzun; Okumak

Hepimiz tatbikatı biliyoruz, değil mi? Bir kod değişikliği üzerinde çalışmayı bitirip bunu yerel makinemizde test ettikten sonra, değişikliği döngüdeki bir sonraki aşamaya aktarırız. Yerel testler oldukça taraflıdır ve ideal olarak değişikliği daha istikrarlı bir ortamda doğrulamak isteriz (ve ayrıca yalnızca değişikliği uygulayan mühendisin bakış açısını takip etmekle kalmayız).
featured image - Değişiklikler Güvenli Bir Şekilde Üretime Nasıl Gönderilir?
 HackerNoon profile picture

Hepimiz tatbikatı biliyoruz, değil mi? Bir kod değişikliği üzerinde çalışmayı bitirip bunu yerel makinemizde test ettikten sonra, değişikliği döngüdeki bir sonraki aşamaya aktarırız. Yerel testler oldukça taraflıdır ve ideal olarak değişikliği daha istikrarlı bir ortamda doğrulamak isteriz (ve ayrıca yalnızca değişikliği uygulayan mühendisin bakış açısını takip etmekle kalmayız).


Burada bir sonraki adım çok doğal görünüyor: Değişiklikleri güvenilir bir hazırlama ortamına aktarın ve değişiklikleri taşımadan önce ortakların (QA'lar, PM'ler, diğer mühendisler) doğrulama konusunda yardım etmesini sağlayın. Bunu, üretime geçmek için yeterince iyi olduğuna inanıncaya kadar hata düzeltme ve yeniden doğrulama takip edecektir. Harika!


Ancak çoğu durumda bu gerçekleşmez. Bunun çeşitli nedenleri olabilir, ancak nedeni ne olursa olsun sonuç, genellikle üretim sunucularındaki değişiklikleri, yeterince iyi bir şekilde test edilmeden veya doğrulanmadan önce tanıtmak zorunda kalmamızdır.


Sorun şu ki... Ya bir şey kırılırsa? Aslında sorunları daha erken nasıl tespit edebiliriz? İyi haber: Üretimde test etme ve doğrulamayı yalnızca sizin ve şirketiniz için güvenli bir uygulama değil, hatta belki de iyi bir fikir haline getirmek için bazı araç ve uygulamaları benimsemek mümkündür.

Temel: Metrikler

Üretimde teste geçmeden önce metriklerden bahsetmemiz gerekiyor: Gönderdiğimiz değişikliğin istenen etkiyi yarattığını, istenmeyen yan etkilere neden olmadığını, ürünün hala stabil olduğunu vb. doğrulamalarına ihtiyacımız var. - Yerleşik ölçümler nedeniyle, değişiklikleri uygulamaya koyarken temelde kör oluyoruz. Makaledeki konuların birçoğunda metriklere değineceğiz, o yüzden dikkat etmemiz gereken iki farklı metrik türüne göz atalım.

İş Metrikleri

Etkiyi değerlendirmek için değişiklikler uygulandıktan sonra KPI'lar, hedefler ve kullanıcı davranışı gibi işle ilgili ölçümler izlenmelidir. Herhangi bir değişiklikten önce etkilenmesi beklenen metrikleri tanımlayın. Neyin değişmemesi gerektiğine dair göstergeler olan korkuluk ölçümleri de aynı derecede önemlidir. Bu korkuluklardaki öngörülemeyen değişiklikler, yeni değişiklikle ilgili sorunları işaret edebilir ve bu da inceleme gerektirebilir.

Teknik Metrikler

İş metrikleri tanımlandıktan sonra teknik metrikleri anlamak da önemlidir. Bunlar, zaman içinde değişiklikler yapıldıkça sistemlerin sağlıklı kalmasını sağlamak için temel öneme sahiptir. Burada sistem kararlılığı, hata oranı, hacim, makine kapasitesi kısıtlamaları vb. hakkında konuşuyoruz.


İyi teknik ölçümler, iş ölçümlerinde gözlemlenen sorunları açıklamak veya gerilemelerin temel nedenini hızlı bir şekilde bulmak için de faydalıdır. Örneğin, son sürümün kullanıma sunulmasından sonra kullanıcıların belirli bir özellikle çok daha az etkileşim kurduğunu gözlemlediğimizi varsayalım. İstek zaman aşımlarındaki veya hata oranlarındaki artış, soruna hangi hizmetlerin/uç noktaların neden olduğunu hızlı bir şekilde gösterebilir.

İzleme

İyi tanımlanmış iş ve teknik ölçümlerimiz var, güzel! Artık bunları takip etmemiz gerekiyor. Bunu yapmanın birçok yolu vardır, ancak ilk ortak adım, zaman içindeki ölçümleri takip eden ve olağandışı ani artışların fark edilmesini kolaylaştıran gösterge tabloları oluşturmaktır. Kontrol panelinin, özellikle işletmeyle alakalı olabilecek belirli segmentlere göre verilerin hızlı bir şekilde filtrelenmesine izin vermesi daha da iyidir. Kontrol panellerini aktif olarak izlemek, yeni bir değişikliğin sistemde yarattığı etkileri hızlı bir şekilde görselleştirmenin iyi bir yoludur. Bazı şirketler aktif izlemenin o kadar önemli olduğunu düşünüyor ki, sorunları mümkün olduğu kadar erken tespit edip çözmek için 7/24 izleme vardiyaları bile uyguluyorlar.


Metrikleri izlemenin bir başka iyi yolu da otomatik algılama ve uyarılardır. Önemli ölçümler için uyarılar, bir şeyler ters gittiğinde gerçek zamanlı bildirim sağlayabilir. Diyelim ki bir özelliği kullanıma sunmaya başladık ve süreç başladıktan birkaç dakika sonra hata oranının belirli bir eşiğin üzerine çıktığını belirten bir uyarı aldık. Bu erken bildirim, değişikliği üretimde daha fazla yaymamızı engelleyebilir ve bizi birçok sorundan kurtarabilir!


Son olarak, ne kadar bilgiye ve hangi koşullar altında ihtiyacımız olduğuna dikkat etmek önemlidir. Gösterge tabloları ürün ve sistem performansına görsel bir bakış sağlamak açısından çok faydalı olsa da, 1000 farklı grafik eklemek netlikten çok kafa karışıklığı getirecektir. Benzer şekilde, günde 1000 uyarı alırsak, bunları araştırıp harekete geçmek imkansızdır ve sonuçta bunlar göz ardı edilir.

Daha güvenli iniş

Metrikler tanımlandı, izleme uygulandı, harika! Şimdi sorunlardan kaçınmamıza, sorunları erken tespit etmemize ve üretimdeki etkileri en aza indirmemize yardımcı olacak bazı araç ve stratejilere göz atalım. Üretim ortamının nasıl kurulduğuna bağlı olarak bunlardan bazılarının uygulanması diğerlerinden daha zor olacak ve belki bir araya getirildiklerinde pek bir anlam ifade etmeyecektir. Ancak buradaki her bir öğe, güvenli ve istikrarlı bir üretim ortamına yaklaşmamıza yardımcı olabilir.

Otomatik Testler

Projeler yolunda gitmediğinde genellikle bir kenara bırakılan otomatik testler, geliştirmeyi hızlandırabilir ve üretimde daha güvenli ve daha hızlı değişiklikler yapabilir. Sorunlar ne kadar erken tespit edilirse o kadar çabuk çözülebilir, böylece süreçte harcanan toplam süre azalır. Değişiklikleri geri alma, düzeltme ve tekrar zorlama süreci genellikle çok streslidir ve değerli zamanınızı alabilir.


Birim, entegrasyon ve uçtan uca testlerle %100 test kapsamını hedeflemek çoğu proje için idealist olabilir. Bunun yerine, çabaya karşı faydaya dayalı testlere öncelik verin. Metrikler bu konuda yol gösterebilir: temel iş özelliklerini kapsamak muhtemelen daha az etkili niş özelliklerden daha önemlidir, değil mi? Temel özelliklerle başlayın ve sistem geliştikçe genişletin.


Üretime yayınlama süreci, üretime dağıtılmadan önce test paketinin çalıştırılmasını içermelidir. Test başarısızlıkları yayınlamayı duraklatarak üretim sorunlarını önleyecektir. Ertesi gün tamamen arızalı olduğunu keşfetmek yerine, bir özelliğin yayınlanmasını geciktirmek tercih edilir.

Test sürümü

Test Sürümü, bir özelliğin son kullanıcılara ulaşmadan önce dahili test için kullanıma sunulması sürecidir. Test sürümü sırasında bu özellik üretimde kullanıma sunulur, ancak bu yalnızca dahili kullanıcıların (çalışanlar, ekip üyeleri vb.) kullanımına sunulur. Bu şekilde, yeni özelliğin beklendiği gibi çalışıp çalışmadığını, gerçek üretim verilerini kullanarak, harici kullanıcıları etkilemeden test edip doğrulayabiliriz.


Test sürümü için farklı stratejiler vardır. Basitleştirilmiş bir genel bakış için bunları iki büyük grupta gruplandırabiliriz:

  1. Tam yapı test sürümü : Bu, örneğin belirli kullanıcılara yeni bir uygulama sürümü yayınlamak ve ardından aynı sürümü mağazalarda genel kullanıma sunmak için yerleşik araçlarımızın bulunduğu iOS/Android uygulamalarında yaygındır.
  2. Seçici test sürümü : Bazen tüm yapıyı test etmek mümkün olmayabilir (hatta istenmez), ancak yine de belirli kullanıcı bilgilerine dayalı olarak test sürümüne izin verebiliriz. Mesela bazı verileri çaprazlayarak çalışanları tespit edebildiğimizi varsayalım. Uygulama daha sonra bu verileri kontrol ederek ve kullanıcıyı istenen davranışa yönlendirerek belirli bir özelliği etkinleştirecek/devre dışı bırakacak şekilde yapılandırılabilir. Uygulama her iki özelliği de içerecek, ancak yalnızca bazı kullanıcılar yeni değişiklikten etkilenecek. Sonraki konularda bu kavramların bazılarına geri döneceğiz.

Kanarya Sürümü

Canary sürümü, üretimdeki değişikliklerin tüm sunuculara aynı anda dağıtılması yerine, değişikliğin sunucuların küçük bir alt kümesine sunulduğu ve bir süre izlendiği bir sürüm sürecidir. Ancak değişikliğin kararlı olduğu onaylandıktan sonra üretim ortamına aktarılır.


Kanarya Sürümü


Bu, yeni özellikleri ve riskli değişiklikleri test etmek için en güçlü araçlardan biridir ve böylece üretimde bir şeyin bozulma ihtimalini azaltır. Değişikliği bir grup kullanıcı üzerinde test ederek, herhangi bir sorun tespit edilirse kullanıma sunma sürecini durdurabilir/geri döndürebilir ve bu durumun kullanıcıların çoğu üzerindeki etkisini önleyebiliriz.

Mavi Yeşil Dağıtım

Bir DevOps uygulaması olan Mavi Yeşil Dağıtım, iki sunucu kümesi (Mavi ve Yeşil) kullanarak ve bunlar arasında üretim trafiğini değiştirerek kesinti sürelerini önlemeyi amaçlamaktadır. Özelliğin kullanıma sunulması sırasında, değişiklikler bir kümede (Yeşil) yayınlanırken diğerinde (Mavi) değişiklik yapılmaz. Sorun çıkması durumunda, önceki sürümde çalışmaya devam ettikleri için trafik hızla Blue sunuculara döndürülebilir.


#Mavi Yeşil Dağıtım

Mavi Yeşil Dağıtım, daha önce tartıştığımız Canary Sürümü ile sıklıkla karşılaştırılmaktadır. Bu tartışmanın ayrıntılarına dalmayacağız ancak hangi araçların işimize daha uygun olduğuna karar verirken bize yardımcı olması açısından bundan bahsetmek önemlidir.

Sonlandırma Anahtarları ve Özellik Geçişleri

Kill switch'ler yazılım mühendisliği bağlamında ortaya çıkmamıştır ve bunların kullanımını anlamanın en iyi yolu, orijinal amaç ve tasarıma bakmaktır. Endüstride kullanılan makinelerde durdurma anahtarları, çok basit bir etkileşimle (genellikle basit bir düğme veya açma/kapama anahtarı) onları mümkün olduğunca çabuk kapatan güvenlik mekanizmalarıdır. Acil durumlar için, bir olayın (örneğin makine arızası) daha kötü bir duruma (yaralanma veya ölüm) neden olmasını önlemek için mevcutturlar.


Yazılım mühendisliğinde, durdurma anahtarları benzer bir amaca hizmet eder: Sistemi çalışır durumda tutmak amacıyla belirli bir özelliği kaybetmeyi (veya sonlandırmayı) kabul ederiz. Uygulama, yüksek düzeyde, genellikle belirli bir değişiklik veya özelliğin giriş noktasına eklenen bir durum kontrolüdür (aşağıdaki kod parçacığına bakın).


 if (feature_is_enabled('feature_x')) {xNewBehaviour();} else {xOldBehaviour();}


Örneğin, yeni bir üçüncü taraf API'ye geçiş işlemi gönderdiğimizi varsayalım. Testlerde her şey yolunda, kanarya sürümünde stabil ve sonrasında değişiklik %100 üretime aktarılıyor. Bir süre sonra yeni API hacimle ilgili sorun yaşamaya başlar ve istekler başarısız olmaya başlar (teknik ölçümleri hatırlıyor musunuz?). Bir acil anahtarımız olduğundan, API istekleri anında eski API'ye döndürülebilir ve önceki bir sürüme dönmemize veya hızlı bir şekilde düzeltme göndermemize gerek yoktur.


Teknik olarak konuşursak, öldürme anahtarları aslında özellik geçişlerinin (diğer adıyla özellik bayrakları) özel bir kullanım durumudur. Konuya girmişken, özellik geçişlerinin bir başka harika faydasından bahsetmeye değer: Ana hat tabanlı geliştirmenin etkinleştirilmesi. Özellik geçişleri sayesinde yeni kod, tamamlanmamış veya henüz test edilmemiş olsa bile güvenli bir şekilde üretime aktarılabilir.

Eski davranışları erişilebilir tutmak

Yukarıda örneklenen kod muhtemelen bazılarımızın uygulamada hem eski hem de yeni davranışların aynı anda yaşaması nedeniyle bunun gerçekten iyi bir kalıp olup olmadığını merak etmesine neden oldu. Bunun muhtemelen kod tabanımız için istediğimiz son durum olmadığına katılıyorum, aksi takdirde kodun her bir parçası if/else cümlecikleriyle çevrelenecek ve kod kısa sürede okunamaz hale gelecektir.


Ancak eski davranışı silmek için her zaman acele etmemeliyiz. Evet, kodun kullanımı durur durmaz temizlemek ve teknik borçlardan kaçınmak çok cazip. Ancak özellik geçişi altında bir süre orada bırakmak da sorun değil. Bazen yeni özelliğin stabil hale gelmesi biraz zaman alabilir ve bir yedekleme seçeneğine sahip olmak, kısa bir süre için de olsa ona geri dönmemiz gerekebileceği ihtimaline karşı güvenli bir mekanizmadır.


Her sürümün yaşam döngüsü farklıdır ve eski koddan kurtulmanın en iyi zamanının ne zaman olduğunu takip etmek iyi bir uygulamadır. Kodu temiz tutmak ve bakım yükünü azaltmak, kodda bu özelliği devre dışı bırakmış olmamıza rağmen, devre dışı bırakıldığından bu yana ne kadar zaman geçtiğine bakıldığında büyük olasılıkla bozulduğu ters durumu önleyecektir.

Gölge testi

Daha güvenli değişiklikler uygulamak için en sevdiğim tekniklerden biri gölge testi veya gölge modu olarak bilinir. Sonuçları karşılaştırmak için hem eski hem de yeni davranışların yürütülmesini, ancak yeni davranışın bazı yan etkilerinin uygun şekilde devre dışı bırakılmasını içerir. Bu basit örneğe bir göz atalım:


 int sum(int a, int b) {int currentResult = currentMathLib.sum(a, b);int newResult = newMathLib.sum(a, b);logDivergences(a, b, currentResult, newResult);return currentResult;}void logSumDivergences(int a, int b, int currentResult, int newResult) {if (currentResult != newResult) {logger.warn(      'Divergence detected when executing {0} + {1}: {2} != {3}',a, b, currentResult, newResult);}}


Her iki toplama işlemi de yürütülse de, yenisi yalnızca farklılıkları karşılaştırmak ve günlüğe kaydetmek için kullanılır. Bu teknik özellikle karmaşık sistem değişikliklerini izlemek için kullanışlıdır ve eski ve yeni davranışlar arasında bir miktar eşitlik olmasını bekliyoruz. Bir başka harika kullanım durumu da pek aşina olmadığımız ürünlerde değişiklik yapmamız gerektiği veya amaçlanan değişiklikten hangi uç durumların etkilenebileceğini iyi bilmediğimiz durumlardır.


Daha karmaşık senaryolarda gölge testini etkinleştirmeden önce bazı yan etkileri devre dışı bırakmamız gerekebilir. Örneğin, kullanıcıları kaydetmek ve veritabanına kaydetmek ve kullanıcı kimliğini döndürmek için yeni bir arka uç API uyguladığımızı varsayalım. Tüm süreci yürütmek için bir gölge veritabanı bile kullanabiliriz, ancak "Kayıt başarılı" e-postasını her arka uç API için bir tane olmak üzere iki kez göndermek kesinlikle iyi bir fikir değildir. Ayrıca aynı örnekte, döndürülen kullanıcı kimliklerini basitçe karşılaştırmak pek yararlı olmayacağından daha derin bir karşılaştırma mantığına ihtiyacımız olacaktır.


Son olarak, nelerin izlenmesi ve test edilmesi gerektiğini ve eşitlik sağlanamadığı takdirde hangi kriterlerin uygulanacağını anlamak önemlidir. Bazı kritik senaryolarda, sonuçlar tamamen aynı olana kadar gölge testini yinelememiz gerekecek. Diğerlerinde, yeni uygulamanın kayıptan daha fazla ek faydalar sunması durumunda bir miktar farklılığın olması sorun teşkil etmeyebilir.

Kütükler

Güçlü korumalara rağmen sistemler bozulabilir. Böyle bir durum meydana geldiğinde, uygun düzeyde ayrıntıyla neler olup bittiğini anlayabilmeliyiz, aksi takdirde etkili bir çözüm bulmak son derece zor olabilir. Günlüklerin günü kurtarmaya geldiği yer burasıdır.


Günlüğe kaydetme yeni bir kavram olmamasına ve uygulanması kolay birçok çözüm bulunmasına rağmen, etkili günlüklerin tutulması zordur. Çoğu zaman günlükler belirsizdir, aşırı karmaşıktır, eksiktir veya ilgisiz girişlerle doludur, bu da sorun gidermeyi zorlaştırır. Ancak günlükler yalnızca sorunları çözmeye yönelik değildir. Doğru günlük kaydı, yeni özelliklerin ve değişikliklerin etkililiğinin doğrulanmasına yardımcı olur. Günlük girişleri örneklenerek kullanıcı yolculukları izlenebilir ve sistemin amaçlandığı gibi çalıştığı doğrulanabilir.

Son düşünceler

Kodu üretime göndermek bazen tehlikeli olabilir ancak süreci daha güvenli hale getirecek birçok stratejimiz var. Bir sorunu tanımlasak bile neyin kabul edilebilir olup olmadığını bilmek de önemlidir. Tüm başarısızlıkların geri dönüşle sonuçlanması gerekmez. Peki ya ciddi bir güvenlik açığını düzeltmeye ya da yeni bir düzenlemeye uymaya çalışıyorsak? Açık kriterlere sahip olmak ve değişikliğin ne kadar kritik olduğunu anlamak, sorun olması durumunda ne zaman iptal edileceğini veya devam edileceğini belirlemek açısından çok önemlidir. Başa dönersek, ana ölçütler karar sürecinde bize yardımcı olmak için oradadır.


Millet, güvenli iniş!