Sıfır Kesinti Dağıtımını Gerçekleştirme


40

Sıfır kesinti süresi kesintisi sağlamaya çalışıyorum, bu sayede kapalı saatlerde daha az ve daha "yavaş" saatlerde veya herhangi bir zamanda teoride konuşlayabilirim.

Şu anki kurulumum biraz basitleştirildi:

  • Web Sunucusu A (.NET Uygulaması)
  • Web Sunucusu B (.NET Uygulaması)
  • Veritabanı Sunucusu (SQL Server)

Mevcut dağıtım işlemim:

  1. Web Sunucusu A ve B'deki siteleri "durdur"
  2. Dağıtılmakta olan uygulamanın sürümü için veritabanı şemasını yükseltin
  3. Web Sunucusunu Güncelle A
  4. Web Sunucusunu Güncelle B
  5. Her şeyi tekrar çevrimiçi duruma getirin

Şuanki problem

Bu, her ay küçük bir kesinti süresine neden olur - yaklaşık 30 dakika. Bunu mesai saatleri dışında yapıyorum, bu yüzden büyük bir sorun değil - ama ondan uzaklaşmak istediğim bir şey.

Ayrıca - gerçekten geri dönmenin yolu yok. Genellikle geri alma DB komut dosyaları yapmıyorum - yalnızca komut dosyalarını yükseltin.

Yük Dengeleyicisini Kaldırma

Bir kerede bir Web Sunucusunu yükseltebilmeyi çok isterim. Web Server A'yı yük dengeleyiciden çıkarın, yükseltin, tekrar çevrimiçi duruma getirin ve ardından Web Server B için tekrarlayın.

Sorun veritabanı. Yazılımımın her sürümünün veritabanının farklı bir sürümüne karşı çalışması gerekiyor - bu yüzden "sıkışmış" durumdayım.

Olası çözüm

Düşündüğüm mevcut bir çözüm, aşağıdaki kuralları kabul ediyor:

  • Bir veritabanı tablosunu asla silmeyin.
  • Bir veritabanı sütununu asla silmeyin.
  • Asla bir veritabanı sütununu yeniden adlandırmayın.
  • Asla bir sütunu yeniden sırala.
  • Saklanan her prosedür versiyonlanmalıdır.
    • Anlamı - 'spFindAllThings' düzenlendiğinde 'spFindAllThings_2' olur.
    • Sonra tekrar düzenlendiğinde 'spFindAllThings_3' olur.
    • Aynı kural, görünümler için de geçerlidir.

Bu biraz aşırı gibi gözükse de, bence sorunu çözdü. Uygulamanın her sürümü DB'ye kesintisiz bir şekilde vuracak. Kod, görünümlerden / depolanan prosedürlerden belirli sonuçlar beklemektedir - ve bu, 'sözleşmeyi' geçerli kılar. Sorun şu ki - sadece özensiz görünüyor. Uygulama bir süre dağıtıldıktan sonra eski saklı yordamları temizleyebileceğimi biliyorum, ancak yalnızca kirli hissediyor. Ayrıca - bu kuralı izleyen tüm geliştiricilere dayanır, bu çoğunlukla olur, ancak birinin bir hata yapacağını hayal ediyorum.

Sonunda - Benim sorum

  • Bu özensiz veya hacky mi?
  • Bu şekilde yapan başka biri var mı?
  • Diğer insanlar bu sorunu nasıl çözüyor?

2
Arka plan planın nerede? Her şeyin çalıştığını ve gerileme olmadığını nasıl test edersiniz?
Deer Hunter

3
Her iki bitişik sürümün aynı anda çalışabilmesini sağlamak için "asla": "sadece" ihtiyacınız yoktur. Bu, yükseltme yollarınızı sınırlandırır, ancak DB şemasını önemli ölçüde değiştiremez hale getirmediğiniz kadar ciddi değildir.
Joachim Sauer

Teşekkürler Joachim ... Mutlak olarak konuşmayı severim, böylece temel fikir açıktır - ama haklısınız, N sürümleri tarafından geriye dönük olarak uyumlu olma politikasına sahip olabiliriz, bu noktada gereksiz DB nesnelerini kaldırabiliriz.
MattW

2
Bir geri alma planı uygulamak isteyeceksiniz. Bir gün ihtiyacın olacak.
Thorbjørn Ravn Andersen

1
Tecrübelerime göre, çoğu web sitesi için olası çözümün çözdüğü problemden daha kötü. Ekleyeceği karmaşıklık şimdi beklediğinizden daha pahalı olacak. Belki de değişiklik yapma ve özellik ekleme konusunda birçok kez daha fazla zaman / çaba harcarsınız. Sadece kesinlikle olamaz web siteleri için bunu dikkate alacağını herhangi , kesinti hiç .
MGOwen

Yanıtlar:


14

Bu, veritabanı destekli yazılım güncellemelerine çok pratik bir yaklaşımdır. Bu edilmiş açıklanan 2003 yılında Martin Fowler ve Pramod Sadalage tarafından ve daha sonra yukarı yazılı Refactoring Veritabanları: Evrimsel Veritabanı Tasarımı .

Özensiz göründüğünü söylerken ne demek istediğini anlayabiliyorum, ama kasıtlı olarak ve öngörüldüğünde ve kullanılmayan yapıları kod tabanından ve veritabanından çıkarmaya zaman ayırırken, artık görünmez bir şekilde kullanıldıklarında yükseltme ve geri alma komut dosyalarına dayalı daha basit çözümler.


5

“Sıfır kesinti süresi”, bu tür bir yaklaşımın olası nedenlerinden yalnızca bir tanesidir. Bir veri modelini geriye doğru uyumlu tutmak, birçok farklı problemle başa çıkmanıza yardımcı olur:

  • veritabanınıza erişen çok fazla yazılım paketiniz varsa, şema değişikliği onları etkiliyorsa hepsini kontrol etmeniz gerekmez (aynı veritabanına erişen programlar yazan birden çok ekip bulunan büyük kuruluşlarda şema değişiklikleri çok zor olabilir)

  • Gerekirse, programlarınızdan birinin eski bir sürümünü kontrol edebilirsiniz ve büyük olasılıkla daha yeni bir veritabanında çalışacaktır (eski programın daha yeni sütunları doğru şekilde işlemesini beklemeniz beklenmediği sürece)

  • arşivlenen verilerin mevcut veritabanı sürümüne içe aktarılması / dışa aktarılması çok daha kolaydır

İşte listeniz için ek bir kural

  • Her yeni sütun ya NULL olmalıdır ya da anlamlı bir varsayılan değer sağlamalıdır.

(bu, yeni sütunları bilmeyen daha eski programların bile veritabanınızda yeni kayıtlar oluştururken hiçbir şeyi bozmayacağından emin olur).

Elbette, bu yaklaşımın tek bir dezavantajı var: Veri modeli kaliteniz zamanla düşebilir. Ayrıca, veritabanınıza erişen tüm uygulamalar üzerinde tam bir kontrole sahipseniz ve örneğin bir sütunu yeniden adlandırırken tüm bu uygulamaları kolayca yeniden değerlendirebilirseniz, işleri daha temiz bir şekilde yeniden değerlendirmeyi düşünebilirsiniz.


4

Bir dağıtımdan diğerine çeşitlilik gösterir.

Elbette, bir tabloyu veya sütunu asla silemezsiniz. Arayüz uyumluluğunu bozan hiçbir şeyi asla değiştiremezsiniz. Her zaman bir soyutlama katmanı ekleyebilirsiniz. Ama o zaman bu soyutlamayı, versiyonunu da sürümlendirmelisin.

Kendinize sormanız gereken soru şudur: Her bir sürüm, şemayı geriye dönük olarak uyumlu olmayacak şekilde değiştiriyor mu?

Çok az sürüm, şemayı bu şekilde değiştirirse, veritabanı sorunu sessizdir. Sadece uygulama sunucularının dağıtımını yapın.

Gördüğüm iki şey, minimum aksama süresi dağıtımında en fazla yardımcı oluyor:

  1. Geriye dönük uyumluluk için çabalayın - en azından tek bir sürümde. Her zaman başaramazsınız, ancak bahse girerim, özellikle her sürüm küçükse, sürümlerinizin% 90 veya daha fazlasında başarabilirsiniz.
  2. Sürüm öncesi ve sürüm sonrası veritabanı komut dosyası var. Bu, uygulama kodunuz dağıtılmadan önce yeni nesnenizi oluşturarak ve uygulama kodu dağıtıldıktan sonra eskisini bırakarak yeniden adlandırma veya arayüz değişikliklerini gerçekleştirmenize olanak sağlar. NULL olabilecek yeni bir sütun eklerseniz, bunu sürüm öncesi betiğinize varsayılan değeri dolduracak bir tetikleyici ile null olarak ekleyebilirsiniz. Daha sonra sürümünüzde, tetiği bırakabilirsiniz.

Umarım dağıtımlarınızın geri kalanı bakım pencereleri için saklanabilir.

Arıza süresi gerektiren birkaç dağıtım ile başa çıkmanıza yardımcı olabilecek diğer fikirler:

  • Kodunuzda geriye dönük uyumluluk oluşturabilir misiniz? Örneğin, kodunuzun birden fazla sonuç kümesini destekleyebilmesinin bir yolu var mı? Bir sütunu int'den çift olarak değiştirmeniz gerekirse, uygulama kodunuz bunu bir dize olarak okuyabilir ve ayrıştırır. Biraz takırdama, ancak serbest bırakma sürecinden geçmek için geçici bir kod varsa, dünyanın sonu olmayabilir.
  • Saklı yordamlar, uygulama kodunuzu şema değişikliklerinden yalıtmanıza yardımcı olabilir. Bu sadece şimdiye kadar gidebilir, ancak biraz yardımcı olur.

2

Biraz fazladan çaba için potansiyel olarak böyle yapabilirsiniz.

  1. Verme işlemini alarak veritabanını yedekleyin
  2. Yedeklemeyi alın ancak bir sürümle yeniden adlandırın, örn. MyDb_2_1
  3. MyDB_2_1 cihazında veritabanı yayınlamayı yürütün
  4. Uygulama havuzunu Web Sunucusu A'da durdurun veya yük dengeleyiciden çıkarın
  5. Web Sunucusu A'yı güncelleyin, uygulama sonrası testlerini çalıştırın ve gerekirse geri alın
  6. Oturum, Web Sunucusu B'yi boşalttı ve Web Sunucusu A'yı tekrar döngüye soktu
  7. Web sunucusu B'yi yükseltin ve ardından yük dengeleyicisine geri koyun

Doğal olarak, web güncellemelerinin yeni Db şemasını göstermesi için yeni config girişlerine ihtiyacı olacaktır. Şey, ayda bir kez yayın yapıyorsanız ve gerçekte geriye dönük olarak uyumlu olmayan kaç tane DB değişikliği yapıyorsunuz? Bunu test ederek, zaman aşımına uğramayan veya belki de en kötü ihtimalle sadece 5 dk.


1
Sunucu A'daki uygulama (ne zaman) yedeğini kaydettikten sonra ancak Sunucu A'yı durdurmadan önce DB'sine yazarsa ne olur? Her zaman bir "güvenlik açığı penceresi" vardır. Bu yazmalar kaybedilecek ve kabul edilemez.
sleske,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.