Strangler İncir Deseni: Monolitik Uygulamaları Taşımanın Güvenli Bir Yolu

Strangler İncir Deseni: Monolitik Uygulamaları Taşımanın Güvenli Bir Yolu

Modern yazılım mühendisliğinde eski monolitik uygulamalar yaygın bir zorluktur. Başarılı bir kod tabanı zamanla o kadar büyür ve birbirine bağlanır ki, basit değişiklikler yapmak riskli hale gelir, dağıtımlar saatler alır ve bireysel özellikleri ölçeklendirmek neredeyse imkansızdır.

Ekipler mikro hizmetlere geçerek sistemlerini modernleştirmeye karar verdiğinde önemli bir soruyla karşı karşıya kalırlar: Mevcut işimizi bozmadan sistemi nasıl yeniden yazabiliriz?

Seçeneklerden biri “Büyük Patlama"nın yeniden yazılmasıdır; yeni sistemi kapalı kapılar ardında sıfırdan inşa etmek ve her şeyi tek bir günde değiştirmek. Ancak bu son derece risklidir ve sıklıkla başarısızlığa yol açar.

Neyse ki daha güvenli, daha güvenilir bir alternatif var: Strangler İncir Deseni. Bu kılavuzda Strangler İncir Deseninin ne olduğunu, neden işe yaradığını ve anlaşılır diyagramlar ve gerçek dünya kodları kullanarak adım adım nasıl uygulanacağını keşfedeceğiz.


Gerçek Dünya Analojisi: Boğucu İncir Fabrikası

Desen, adını tropikal yağmur ormanlarına özgü bir bitki olan boğaz incirinden almıştır.

Boğucu bir incir tohumu, mevcut bir “konakçı” ağacın üst dallarında filizlenir. İncir yerden yukarıya büyümek yerine aşağıya doğru büyür:

  1. Köklerini konakçı ağacın gövdesinden aşağıya, orman zeminine ulaşana ve toprağa demirleyene kadar gönderir.
  2. Zamanla daha fazla kök büyür, konağın etrafına sarılır ve birbirine kaynaşır.
  3. İncir, ışığın konakçı ağaca ulaşmasını engelleyen yapraklar çıkarır.
  4. Sonunda, ev sahibi ağaç ölür ve çürür, yerine içi boş, boğucu bir incir ağacı kalır.

Yazılım mimarisinde, eski monolit ana makine ağacıdır ve yeni mikro hizmetler boğucu incirdir. Yeni hizmetleri monolitin kenarları etrafında inşa ediyoruz ve monolit tamamen kapatılıncaya kadar trafiği yavaş yavaş eski sistemden uzaklaştırıyoruz.


“Big Bang"in Yeniden Yazılması Neden Başarısız Oldu?

Strangler Fig modelinin mekaniğine dalmadan önce, alternatifin (tamamen yeniden yazmanın) neden bu kadar tehlikeli olduğunu anlayalım:

  • Aylar (veya Yıllar) Boyunca Değer Yok: Geliştiriciler kod yazmak için uzun zaman harcarlar, ancak projenin tamamı tamamlanana kadar bunların hiçbiri yayınlanmaz.
  • Kapsam Kayması: İki yıllık yeniden yazım sırasında iş ihtiyaçlarının değişmesi. Hedef hareket eder ve yeni sistemin, yeniden yazma başladığında mevcut olmayan özellikleri desteklemesi gerekir.
  • Eksik Örtük Davranış: Monolitler, yıllar süren belgelenmemiş hata düzeltmeleri ve son durum işlemleri içerir. Temiz bir yeniden yazma işlemi genellikle bu ayrıntıları unutur.
  • Yüksek Dağıtım Riski: Devasa eski bir sistemi kapatıp yenisini aynı anda açmak, bir şeyler ters giderse çok büyük bir patlama yarıçapı oluşturur.

Strangler İncir Deseni Nasıl Çalışır?

Strangler İncir Deseninin temel fikri artımlı geçiştir. Sistemin tamamını taşımak yerine, tek seferde küçük bir özelliği veya “dilimi” taşırsınız.

Strangler İncir Deseni Geçiş Aşamaları Diyagramı

Geçiş süreci beş temel aşamada gerçekleştirilir:

1. Sınırlı Bir Bağlam Belirleyin

Monolitinize bakın ve çıkarılması kolay tek, bağımsız bir iş yeteneği belirleyin. İyi adaylar şunları içerir:

  • Sık sık değişen özellikler (böylece ekip bağımsız dağıtımlardan hızla yararlanır).
  • Geçiş hattını test etmek için basit, düşük riskli özellikler (statik SSS veya kullanıcı tercihleri ​​bölümü gibi).
  • Temiz, iyi tanımlanmış veritabanı sınırlarına sahip özellikler.

2. Yeni Mikro Hizmeti Uygulayın

Tanımlanan yeteneği yepyeni, modern bir mikro hizmet olarak oluşturun. Bu hizmetin kendi veritabanı, kendi dağıtım hattı vardır ve modern teknoloji yığınları kullanılarak oluşturulmuştur. En önemlisi, monolitteki eski özellik şimdilik aktif ve değişmeden kalıyor.

3. Durdurma Katmanını Tanıtın

Taşıma işlemini kullanıcılarınız için şeffaf hale getirmek amacıyla uygulamanın önüne bir Durdurma Katmanı (API Ağ Geçidi veya Ters Proxy gibi) eklersiniz. Artık tüm istemci trafiği önce bu ağ geçidine gidiyor.

Başlangıçta ağ geçidi tüm isteklerin %100’ünü eski monolite yönlendirir.

4. Trafiği Kademeli Olarak Geçiştirin

Yeni mikro hizmet tamamen test edilip hazır olduğunda, Durdurma Katmanındaki yönlendirme kurallarını güncellersiniz. Geçirilen özelliğe (ör. /api/users) ilişkin istekleri monolite yönlendirmek yerine ağ geçidi, bunları yeni mikro hizmete yönlendirir.

Diğer tüm istekler monolite gitmeye devam ediyor. Yeni hizmet başarısız olursa veya hatalar ortaya çıkarsa, trafiği monolite geri yönlendirmek için ağ geçidini hızlı bir şekilde güncelleyebilir, böylece minimum kesinti sağlayabilirsiniz.

5. Hizmetten Çıkarma ve Tekrarlama

Yeni mikro hizmet bir süre istikrarlı bir şekilde çalıştıktan sonra eski monolitin içindeki ilgili kodu güvenle silebilirsiniz.

Daha sonra bir sonraki özelliği seçip işlemi tekrarlarsınız. Zamanla monolit, hiç trafik kalmayana kadar küçülür ve eski sunucuyu tamamen kullanımdan kaldırabilirsiniz.


Durdurma Katmanı: Ekspres Yönlendirme Örneği

Strangler İncir deseninin kalbi Kesme Katmanı‘dır. İstemci uygulamalarını (web uygulamaları, mobil uygulamalar) değiştirmeden istekleri yönlendirmenize olanak tanır.

Burada Express tabanlı bir ağ geçidi proxy’si kullanan pratik bir Node.js örneği verilmiştir. İstekleri dinamik olarak yönlendirir: Gelen istekler, taşınan yollarla eşleşiyorsa yeni hizmetlere gider; aksi takdirde eski monolite geri dönerler.

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
const PORT = 8080;

// Configuration: Target server URLs
const LEGACY_MONOLITH_URL = 'http://legacy-monolith-server:3000';
const NEW_USER_SERVICE_URL = 'http://new-user-service:3001';
const NEW_PAYMENT_SERVICE_URL = 'http://new-payment-service:3002';

// Simple logging middleware to track traffic distribution
app.use((req, res, next) => {
    console.log(`[ROUTE LOG] Incoming request: ${req.method} ${req.url}`);
    next();
});

// 1. MIGRATED: User registration & profile requests route to the new microservice
app.use('/api/users', createProxyMiddleware({
    target: NEW_USER_SERVICE_URL,
    changeOrigin: true,
    pathRewrite: {
        '^/api/users': '/v1/users', // Translate path format if necessary
    }
}));

// 2. MIGRATED: Payment transactions route to the new payment microservice
app.use('/api/payments', createProxyMiddleware({
    target: NEW_PAYMENT_SERVICE_URL,
    changeOrigin: true
}));

// 3. FALLBACK: All other legacy routes automatically default to the Monolith
app.use('/', createProxyMiddleware({
    target: LEGACY_MONOLITH_URL,
    changeOrigin: true
}));

app.listen(PORT, () => {
    console.log(`Interception Gateway routing traffic successfully on port ${PORT}`);
});

Veritabanını Kullanmak: En Zor Kısım

API trafiğini yönlendirmek nispeten kolay olsa da, verileri yönetmek monolitik geçişin en zorlu yönüdür. Bir monolit genellikle tabloların yüksek düzeyde birleştiği tek ve büyük bir veritabanına sahiptir.

Bir hizmeti çıkardığınızda, onun verilerini de çıkarmanız gerekir. Bunu ele almak için iki yaygın yaklaşım vardır:

  1. İkili Yazma: Durdurma katmanı veya uygulama, geçiş aşamasında verileri hem eski veritabanına hem de yeni hizmet veritabanına aynı anda yazar. Bu, her iki veritabanını da senkronize halde tutar.
  2. Veri Yakalamayı Değiştir (CDC): Debezium gibi bir araç, eski veritabanı işlem günlüğünü izler ve değişiklikleri neredeyse gerçek zamanlı olarak otomatik olarak yeni mikro hizmet veritabanına aktarır.

Veritabanlarının tamamen senkronize edildiğinden ve yeni veritabanının doğru olduğundan emin olduktan sonra okuma trafiğini yeni hizmete geçirir ve eski tabloları kapatırsınız.


Karşılaştırma: Big Bang Rewrite ile Strangler Fig

Özellik / Metrik Büyük Patlama Yeniden Yazım Strangler İncir Deseni
Risk Düzeyi Son Derece Yüksek Düşük ve Yönetilen
Geri Bildirim Döngüsü Çok Yavaş (yalnızca sonunda) Hızlı (sürekli üretim testleri)
Geri Alma Stratejisi Sabit (yedeklerin geri yüklenmesini gerektirir) Kolay (ağ geçidindeki rota kurallarını değiştirin)
İşletme Etkisi Yıkıcı Sıfır kesinti süresi
Sistem Karmaşıklığı Yüksek (yapım aşamasında) Yüksek (geçiş aşamasında)
Dağıtım Süresi Devasa tek sürüm Küçük, sık güncellemeler

Çözüm

Strangler Fig Pattern, monolitlerin mikro hizmetlere taşınmasına yönelik endüstri standardıdır. Eski kodun tamamını bir defada değiştirmek yerine aşamalı olarak değiştirerek, “Büyük Patlama” hatası riskini ortadan kaldırırsınız.

Dağıtımları küçük tutar, gerçek üretim trafiğinden anında geri bildirim sağlar ve ekibinizin geçiş yaşam döngüsü boyunca iş değeri sağlamaya devam etmesine olanak tanır.

Veritabanı geçişini yönetmek ve iki paralel sistemi çalıştırmak operasyonel karmaşıklığı artırırken sunduğu güvenlik, öngörülebilirlik ve kararlılık, onu modern bulut geçişleri için tercih edilen seçenek haline getiriyor.


Ghaznix Blogunda daha fazla yazılım geliştirme ve arka uç mühendisliği öngörülerini keşfedin →