Blog'a Dön
Modern Uygulamalar İçin Ölçeklenebilir Mimari Kalıpları
Mühendislik
8 dk okuma

Modern Uygulamalar İçin Ölçeklenebilir Mimari Kalıpları

Milyonlarca isteği karşılayan sistemleri, kod kalitesini ve geliştirici deneyimini koruyarak nasıl tasarlıyoruz.

Ölçeklenebilir yazılım geliştirmek sadece daha fazla trafiği karşılamakla ilgili değildir. İşletme ihtiyaçlarınızla birlikte zarif bir şekilde büyüyen sistemler oluşturmakla ilgilidir. Innoware olarak yıllar içinde mimari yaklaşımımızı rafine ettik ve bu yazıda geliştirdiğimiz her ürüne rehberlik eden kalıpları ve ilkeleri paylaşacağız.

Yeni bir ürün başlatırken, ilk önemli konuşmalardan biri ölçek hakkında olur. İlk günden aşırı mühendislik yapmak istediğimiz için değil, ilk birkaç haftada alınan mimari kararların bir ürünün kendi başarısından sağ çıkıp çıkamayacağını belirleyebildiği için. Temeller doğru olmadığında ürünler yük altında çökebilir; iyi tasarlanmış sistemler ise beklenmedik trafik artışlarını zarifçe karşılar.

Domain-Driven Design

Her projeye iş alanının derinlemesine anlaşılmasıyla başlıyoruz. Bu sadece bir formalite değil, her projenin en önemli aşamasıdır. Paydaşlarla atölyeler düzenliyoruz, iş süreçlerini haritalıyoruz ve yazılımın modellemesi gereken temel kavramları belirliyoruz. Yazılımı teknik kaygılar yerine iş kavramları etrafında yapılandırmak, hem geliştiriciler hem de iş kullanıcıları için sezgisel sistemler oluşturur.

Pratikte bu, kodun iş sürecinin bir tanımı gibi okunması anlamına gelir. Bir OrderService sadece tablolar arasında veri taşımaz. Siparişlerin nasıl oluşturulduğu, doğrulandığı, karşılandığı ve takip edildiğinin tüm iş mantığını kapsar. İş gereksinimleri değiştiğinde (ve her zaman değişir), değiştirilmesi gereken kod tam beklediğiniz yerde olur.

Sınırlı bağlamlar (bounded contexts), sistemin farklı bölümleri arasında net sınırlar çizer. Bir kimlik doğrulama bağlamındaki "Kullanıcı", faturalandırma bağlamındaki "Kullanıcı"dan temelden farklıdır ve bunları aynı varlık olarak ele almak sistemi kırılgan yapan sıkı bağımlılıklar oluşturur.

Olay Tabanlı Mimari

Karmaşık iş akışlarını yönetmesi gereken sistemler için olay tabanlı kalıplar son derece değerlidir. Servislerin doğrudan birbirini çağırarak bir bağımlılık ağı oluşturması yerine, her servis ne olduğuna dair olaylar yayınlar ve diğer servisler bu olaylara tepki verir.

Bir e-ticaret senaryosunu düşünün: sipariş verildiğinde, sipariş servisi bir "SiparişOluşturuldu" olayı yayınlar. Envanter servisi stok ayırır, ödeme servisi tahsilatı başlatır, bildirim servisi onay e-postası gönderir ve analitik servisi olayı kaydeder. Hepsi bağımsız, hepsi asenkron. Bildirim servisi bakım için kapalıysa, siparişler yine normal şekilde işlenir ve bildirimler servis kurtarıldığında gönderilir.

Bu kalıp ayrıca sistemi doğal olarak genişletilebilir yapar. Sadakat puanı özelliği mi eklemeniz gerekiyor? "SiparişOluşturuldu" olaylarını dinleyen yeni bir servis oluşturun. Mevcut kodda hiçbir değişiklik gerekmez.

CQRS Kalıbı

Command Query Responsibility Segregation (CQRS), modern mimarinin en etkili kalıplarından biridir. Temel fikir basittir: veri yazmak için optimal olan veri modeli, okumak için nadiren optimaldir. Normalize edilmiş ilişkisel şema veri tutarsızlıklarını önler ancak karmaşık sorguları yavaşlatır. Denormalize edilmiş okuma modeli sorguları hızlandırır ancak güncellemeleri karmaşıklaştırır.

CQRS ile her bir kaygı için ayrı modeller tutulur. Yazma işlemleri, iş kurallarını uygulayan ve yetkili veri deposunu güncelleyen komut işleyicilerinden geçer. Okuma işlemleri, olaylar aracılığıyla asenkron olarak güncellenen optimize edilmiş okuma modellerinden sorgulanır. Sonuç: yazma işlemleri tutarlı kalırken, okuma işlemleri hızını korur.

Kod Olarak Altyapı

Tüm altyapımız kod olarak tanımlanır, Git'te sürümlenir ve uygulama kodu gibi pull request'ler aracılığıyla incelenir. Bulut kaynakları için Terraform, konteynerleştirme için Docker ve orkestrasyon için Kubernetes manifest'leri kullanıyoruz. Bu yaklaşım, staging ortamlarının gerçekten production ile aynı olmasını, tüm altyapımızı dakikalar içinde sıfırdan yeniden oluşturabilmemizi ve her altyapı değişikliğinin bir denetim izine sahip olmasını sağlar.

Altyapı-olarak-kod sadece bir DevOps pratiği değil, bir güvenilirlik pratiğidir. Bir production olayı meydana geldiğinde, altyapının kod olarak tanımlanmış olması, ekiplerin güvenle değişiklik yapabilmesi, gerekirse geri alabilmesi ve tam olarak neyin ne zaman değiştiğini anlayabilmesi anlamına gelir.