Mavi-Yeşil Dağıtım: Kesintisiz Yayına Almanın En Sade Yolu

Mavi-Yeşil Dağıtım: Kesintisiz Yayına Almanın En Sade Yolu

İki özdeş ortam, tek anahtar. Mavi-yeşil dağıtım hem kesintiyi hem de geri alma süresini saniyelere indirir.

Mavi-yeşil dağıtım, aynı uygulamanın iki özdeş kopyasını çalıştırıp trafiği aralarında tek hamlede çevirme yöntemidir. Biri canlıya hizmet ederken (mavi), diğeri (yeşil) yeni sürümü barındırır. Anahtar çevrildiğinde geçiş anlıktır; bir şey ters giderse aynı anahtar geri alınır.

Mavi-yeşil dağıtımın adımları
Geri alma, yeni bir dağıtım değil; sadece anahtarı eski konumuna almaktır.

Çözdüğü asıl problem geri almadır

Çoğu ekip dağıtımın kendisini değil, geri almayı yanlış kurgular. "Sorun çıkarsa eski sürümü tekrar dağıtırız" cümlesi kulağa makul gelir ama pratikte 6-10 dakika sürer ve bu süre boyunca kullanıcılar hatayı yaşamaya devam eder. Mavi-yeşil düzende geri alma bir dağıtım değil, bir sembolik bağ değişimidir — saniyeler sürer. Bu konuyu geri alma planı olmayan dağıtım yazımızda ilkesel olarak ele almıştık; burada uygulamasına bakıyoruz.

Dizin düzeni

Bash
/var/www/uygulama/
├── mavi/          # sürüm A
├── yesil/         # sürüm B
├── ortak/         # ikisinin PAYLAŞTIĞI kalıcı veri
│   ├── .env
│   ├── writable/
│   └── uploads/
└── canli -> mavi  # nginx bu sembolik bağı gösterir

Kritik ayrıntı ortak/ dizinidir. Yüklenen dosyalar ve günlükler sürüm dizinlerinin içinde durursa, anahtar çevrildiğinde kullanıcı yüklemeleri "kaybolur". Bu, mavi-yeşil kurulumlarında en sık yapılan hatadır.

Dağıtım betiği

Bash
#!/usr/bin/env bash
set -euo pipefail          # hata olursa DUR: yarım dağıtım en kötü durumdur

KOK=/var/www/uygulama
AKTIF=$(basename "$(readlink -f "$KOK/canli")")
PASIF=$([ "$AKTIF" = "mavi" ] && echo "yesil" || echo "mavi")

echo "Aktif: $AKTIF → Pasif ortama kuruluyor: $PASIF"

# 1) Yeni sürümü pasif ortama kur
rm -rf "${KOK:?}/$PASIF"
git clone --depth 1 --branch "${1:-main}" git@sunucu:proje.git "$KOK/$PASIF"
cd "$KOK/$PASIF"
composer install --no-dev --optimize-autoloader --no-interaction

# 2) Paylaşılan kaynakları bağla (sürüm dizininde KALICI veri tutulmaz)
ln -sfn "$KOK/ortak/.env"      "$KOK/$PASIF/.env"
rm -rf "$KOK/$PASIF/writable"  && ln -sfn "$KOK/ortak/writable" "$KOK/$PASIF/writable"
rm -rf "$KOK/$PASIF/uploads"   && ln -sfn "$KOK/ortak/uploads"  "$KOK/$PASIF/uploads"

# 3) Geriye uyumlu göçleri çalıştır (aşağıdaki kurala bakın)
php spark migrate --all

# 4) Sağlık kontrolü: pasif ortamı KENDİ portundan sına
php -S 127.0.0.1:8099 -t "$KOK/$PASIF/public" &
SUNUCU_PID=$!
sleep 2

if ! curl -fsS --max-time 5 http://127.0.0.1:8099/saglik | grep -q '"durum":"ok"'; then
  kill $SUNUCU_PID
  echo "Sağlık kontrolü BAŞARISIZ — trafik çevrilmedi." >&2
  exit 1
fi
kill $SUNUCU_PID

# 5) Anahtarı çevir (atomik): önce geçici bağ, sonra yeniden adlandır
ln -sfn "$KOK/$PASIF" "$KOK/canli.yeni"
mv -Tf "$KOK/canli.yeni" "$KOK/canli"
sudo systemctl reload php8.2-fpm

echo "Yayında: $PASIF (geri almak için: ln -sfn $KOK/$AKTIF ...)"

mv -Tf ile yapılan sembolik bağ değişimi atomiktir: hiçbir istek "bağ yok" durumuna denk gelmez. rm + ln ikilisi ise arada milisaniyelik bir boşluk bırakır ve o anda gelen istekler 500 alır.

Sağlık kontrolü ucu ne dönmeli?

Sadece "200 OK" yetmez; uygulamanın gerçekten çalışabilir durumda olduğunu kanıtlamalıdır.

PHP
public function saglik()
{
    $kontroller = [];

    try {
        db_connect()->query('SELECT 1');
        $kontroller['veritabani'] = 'ok';
    } catch (\Throwable $e) {
        $kontroller['veritabani'] = 'hata';
    }

    $kontroller['yazilabilir'] = is_writable(WRITEPATH) ? 'ok' : 'hata';
    $kontroller['surum']       = trim((string) @file_get_contents(ROOTPATH . 'SURUM')) ?: 'bilinmiyor';

    $saglikli = ! in_array('hata', $kontroller, true);

    return $this->response
        ->setStatusCode($saglikli ? 200 : 503)
        ->setJSON(['durum' => $saglikli ? 'ok' : 'bozuk'] + $kontroller);
}

Dağıtım betiğini ve komutları tek bir dosyada toplamak isterseniz Makefile bu iş için yeterlidir.

Veritabanı: tek gerçek kısıt

Mavi ve yeşil aynı veritabanını paylaşır. Bu, geri almayı ancak şema geriye uyumluysa mümkün kılar. Kural nettir: sütun silme, yeniden adlandırma ve tip daraltma tek adımda yapılmaz. Bunun yerine genişlet-taşı-daralt yaklaşımı kullanılır ve daraltma adımı, eski sürüme dönme ihtimali ortadan kalktıktan sonraki dağıtıma bırakılır. Sıfır kesintili göç yazımız bu akışı adım adım anlatıyor.

Geçiş anında dosya sunumunu uygulama sunucusundan ayırmak da yükü azaltır; imzalı URL yaklaşımı bu ayrımı kurar.

Maliyet ve alternatifler

Mavi-yeşil, iki kat uygulama sunucusu ister. Tek makinede iki dizinle çalışıyorsanız maliyet yalnızca disktir; ayrı örnekler kullanıyorsanız gerçek bir bulut faturası kalemi oluşur — faturayı şişiren görünmez kalemler arasında bu tarz ikiz ortamlar sık geçer. Kademeli yayın (canary) daha az kaynak ister ama geri alma o kadar keskin değildir. CI/CD kurulumunuzda hangisinin uygun olduğunu, geri alma süresi hedefinize göre seçin. Nginx tarafındaki yapılandırma seçenekleri için Nginx başlangıç kılavuzu yeterli bir referanstır.

Sonuç

Mavi-yeşil dağıtımın değeri hızlı yayına almakta değil, hızlı geri dönmektedir. Kurulumun omurgası dört maddedir: kalıcı veriyi sürüm dizinlerinin dışına alın, trafiği çevirmeden önce pasif ortamda gerçek bir sağlık kontrolü çalıştırın, anahtarı atomik biçimde çevirin ve şema göçlerini her zaman geriye uyumlu tutun. Bu dördü yerindeyse üretimde bir sorunla karşılaştığınızda tartışacağınız şey "geri alalım mı?" değil, yalnızca "ne zaman geri alalım?" olur — çünkü maliyeti birkaç saniyeye inmiştir.

Beğeniniz benzer içerikleri öne çıkarmamıza yardımcı olur.

Sık Sorulan Sorular

Evet. İki ayrı dizin ve bir sembolik bağ yeterlidir; maliyeti yalnızca disk alanıdır. Ayrı sunucu kullanmak donanım arızasına karşı da koruma sağlar, ancak dağıtım riskini azaltmak için tek sunucudaki dizin yaklaşımı çoğu ekip için fazlasıyla yeterlidir.

Oturumlar dosya tabanlıysa ve sürüm dizini içinde tutuluyorsa kaybolur. Bu yüzden oturum deposu paylaşılan bir yerde — veritabanı, Redis veya ortak dizin — olmalıdır. Aynı kural önbellek ve kuyruk için de geçerlidir.

Hemen silmeyin. En az bir gün ayakta bırakmak, gecikmeli ortaya çıkan hatalarda anında geri dönüş imkânı verir. Disk sıkıntısı varsa iki sürüm geriye kadar saklayıp gerisini otomatik temizleyen bir görev tanımlayın.

İşçiler de anahtarla birlikte yeni sürüme geçmelidir, ama çalışan bir işi yarıda kesmemek için önce yeni işleri almayı durdurup mevcut işi bitirmelerini beklemek gerekir. Kuyruk mesajlarının her iki sürüm tarafından da anlaşılabilir olması, aynı geriye uyumluluk kuralının kuyruk tarafındaki karşılığıdır.

S
superadmin

Bu yazıyı hazırladı. Sorularınız için iletişim sayfasından ulaşabilirsiniz.

Yorumlar (0)

Bu yazıya henüz yorum yapılmamış. İlk yorumu siz yazın!

Yorum Yaz

Yorumunuz onaylandıktan sonra yayınlanır. Ekibimiz gerekirse konuyla ilgili bir yanıt da paylaşır.

En az 10 karakter.