Mimari

Monolit mi, mikroservis mi?

Monolit mi, mikroservis mi? Erken aşamada çoğu ürün için doğru yanıt modüler bir monolittir. Dağıtık yapının bedelini ve ne zaman değdiğini anlatıyoruz.

Kapak görseli: Monolit mi, mikroservis mi?

Monolit mi, mikroservis mi sorusunun erken aşamadaki yanıtı çoğu zaman aynıdır: tek parça ama içi düzenli bir uygulamayla, yani modüler bir monolitle başlayın. Yeni bir ürünün ihtiyacı parçaları ayrı ayrı yayınlamak değil, hızlı ve güvenli değişebilmektir. Mikroservisler gerçek bir sorunu çözer, ama o sorun çoğu üründe henüz yoktur.

Monolit ve mikroservis ne demek?

Monolit, tek bir uygulama olarak yazılan ve tek seferde yayınlanan yazılımdır. Üyelik, ödeme, raporlama gibi bölümlerin hepsi aynı kod tabanında durur ve aynı veritabanını kullanır.

Mikroservis mimarisinde ise ürün, birbirinden bağımsız küçük uygulamalara bölünür. Her biri kendi işini yapar, kendi verisini tutar ve diğerleriyle ağ üzerinden konuşur. Her biri ayrı yayınlanabilir.

Arada üçüncü bir yol vardır ve yazının asıl konusu odur: modüler monolit. Tek uygulama olarak yayınlanır, ama içindeki bölümler arasında net sınırlar vardır.

Monolit mi, mikroservis mi: neden bu kadar tartışılıyor?

Mikroservisler, çok büyük ekipleri olan şirketlerin sorununu çözmek için yaygınlaştı. Yüzlerce geliştirici aynı uygulama üzerinde çalıştığında birbirinin işini beklemeye başlar. Ürünü bağımsız parçalara bölmek, ekiplerin birbirini beklemeden yayın yapmasını sağlar.

Sorun şu ki bu çözüm, o sorunu yaşamayan ekipler tarafından da benimsendi. Üç kişilik bir ekibin birbirini bekleme sorunu yoktur. Ama mikroservislerin getirdiği yükün tamamını taşır.

Dağıtık yapının bedeli ilk gün başlar

Mikroservislerin faydası ürün büyüdükçe ortaya çıkar. Bedeli ise ilk günden ödenir.

  • Ağ hataları: aynı uygulama içindeki bir çağrı ya çalışır ya çalışmaz. Ağ üzerinden yapılan çağrı gecikebilir, yarıda kalabilir, iki kez ulaşabilir. Her biri için ayrı önlem gerekir.
  • Veri tutarlılığı: bir işlem iki ayrı servisin verisini değiştiriyorsa, biri başarılı olup diğeri başarısız olduğunda ne olacağı tasarlanmalıdır.
  • Yayın koordinasyonu: servisler birbirine bağlıdır. Birinde yapılan değişiklik diğerini bozabilir; sürümlerin uyumu izlenmelidir.
  • İzleme: bir hata oluştuğunda hangi serviste başladığını bulmak için isteği servisler boyunca takip eden ek araçlar gerekir.
  • Geliştirme ortamı: tek bir özelliği denemek için birkaç servisi birden çalıştırmak gerekir.

Asıl ihtiyaç modülerliktir

Mikroservislerden beklenen asıl fayda düzendir: her bölümün sorumluluğu belli olsun, bir yerde yapılan değişiklik başka bir yeri bozmasın. Bu düzen için ayrı uygulamalar şart değildir.

Modüler bir monolitte uygulama tek parçadır, ama içi bölümlere ayrılmıştır: üyelik, faturalama, raporlama gibi. Her bölüm, yani modül, kendi verisinin sahibidir. Diğer modüller o veriye doğrudan dokunmaz; modülün sunduğu belirli işlevler üzerinden ister.

Bu sınırlar bugün işe yarar: kod daha kolay okunur, değişiklik daha güvenli olur. Yarın da işe yarar: bir modülün gerçekten ayrılması gerekirse, nereden ayrılacağı bellidir.

Düzensiz bir monolit ise kötü ünün asıl kaynağıdır. Her şeyin her şeye dokunduğu bir kod tabanı zamanla değiştirilemez hâle gelir. Çare onu servislere bölmek değildir; düzensiz bir monolit bölününce düzensiz bir dağıtık sistem olur, bu da daha kötüsüdür.

İki yaklaşım yan yana

Karşılaştırma, erken aşamadaki küçük bir ekip düşünülerek yapılmıştır.

Modüler monolit ve mikroservislerin karşılaştırması
KonuModüler monolitMikroservisler
YayınTek uygulama, tek adımHer servis ayrı; uyum izlenir
VeriTek veritabanı, tek işlemde tutarlıServis başına veri; tutarlılık ayrıca tasarlanır
Hata ayıklamaTek yerde izlenirServisler arası izleme gerekir
Değişiklik hızıKüçük ekipte yüksekKüçük ekipte düşük, büyük ekipte yüksek
İşletme yüküDüşükYüksek
Bağımsız ölçeklenmeUygulamanın tamamı birlikteHer servis ayrı
Uygun olduğu durumErken aşama, küçük ve orta ekipBirçok bağımsız ekip, farklı yük profilleri

Bir parça ne zaman ayrılmalı?

Bir modülü ayrı bir servise çıkarmak için somut bir neden gerekir. Geçerli nedenler bellidir.

  • Ayrı ölçeklenmesi gerekiyorsa: bir bölüm diğerlerinden çok daha fazla yük alıyorsa.
  • Farklı bir çalışma ortamı istiyorsa: örneğin uzun süren işlemler ya da farklı bir programlama dili gerektiren bir iş.
  • Daha sıkı güvenlik ayrımı gerekiyorsa: ödeme ya da hassas veri işleyen bir bölüm.
  • Ayrı bir ekip tarafından, ayrı bir takvimle geliştiriliyorsa.
  • Arızası diğerlerini etkilememesi gerekiyorsa.

Tahmine değil, gözleme göre karar verin

"İleride çok büyüyeceğiz" geçerli bir neden değildir. Hangi bölümün yük alacağını ürün yayına girmeden bilemezsiniz; tahminler çoğu zaman yanılır. Yanlış yerden bölünmüş bir sistem, hiç bölünmemiş olandan daha zor düzeltilir.

Karar, ölçülen bir soruna dayanmalıdır. Hangi bölüm yavaşlıyor, hangi iş kuyrukta bekliyor, hangi değişiklik diğerlerini sürekli bozuyor? Bu soruların yanıtı ortaya çıktığında neyi ayıracağınız da belli olur.

Büyümeden önce hangi kararların gerçekten erken verilmesi gerektiğini SaaS mimarisi yazımızda anlatıyoruz. Servislere bölmek o listede yoktur.

Ayrım yolunu açık bırakın

Monolitle başlamak, ileride ayrılma imkânını kapatmak demek değildir. Birkaç alışkanlık bu yolu açık tutar.

  • Modüller birbirinin verisine doğrudan dokunmaz; yalnızca belirli işlevler üzerinden konuşur.
  • Dış servislerle bağlantılar ara katmanların arkasında durur; sağlayıcı değişince tek yer değişir.
  • Uzun süren işler baştan arka plana alınır.
  • Modüller arasındaki bağımlılıklar tek yönlü tutulur; iki modül birbirine bağımlı olmaz.
  • Yük ve hata düzenli olarak ölçülür.

Biz nasıl başlıyoruz?

İlk sürümleri modüler bir monolit olarak kurarız. Bunun nedeni basittir: erken aşamada en değerli şey, kullanıcıdan gelen geri bildirime hızlı yanıt verebilmektir. Tek uygulama, tek veritabanı ve tek yayın adımı bunu sağlar.

Bir bölümün ayrılması gerektiğini gösteren bir ölçüm ortaya çıktığında, o bölümü ayırırız. O güne kadar ürünün enerjisi altyapıya değil, kullanıcıya gider.

Bu yaklaşım süreyi de doğrudan etkiler. İlk sürümün takvimini neyin belirlediğini MVP geliştirme süresi yazımızda bulabilirsiniz.

Erken bölmenin bedeli

Örnek senaryo: Üç kişilik bir ekip, işletmeler için bir rezervasyon ürünü geliştiriyor. İleride büyüyeceklerini düşünerek ürünü baştan beş servise bölüyorlar: kullanıcılar, rezervasyonlar, ödemeler, bildirimler, raporlar.

İlk müşteri basit bir şey istiyor: rezervasyon iptal edildiğinde ödeme iade edilsin ve müşteriye bildirim gitsin. Bu tek istek üç servise dokunuyor. Üçü de ayrı değiştiriliyor, ayrı yayınlanıyor. İade başarılı olup bildirim gitmediğinde hatanın nerede olduğunu bulmak yarım gün sürüyor.

Ekip haftalarını özellik yazmak yerine servisleri konuşturmakla geçiriyor. Aynı ürün tek uygulama olsaydı, bu istek tek bir yerde, tek bir işlem içinde çözülürdü. Bu anlatım kurgusaldır; gerçek bir ekibi tarif etmez.

Sık duyulan itirazlar

Monolitle başlama önerisine karşı birkaç itiraz sık gelir. Her biri bir ölçüde haklıdır, ama erken aşamada geçerli değildir.

"Monolit ölçeklenmez." Ölçeklenir. Tek bir uygulamanın birden fazla kopyasını çalıştırmak mümkündür ve çoğu ürün için uzun süre yeterlidir. Darboğaz genellikle uygulamanın yapısı değil, veritabanı sorgularıdır.

"Sonradan bölmek çok zor olur." Düzensiz bir monoliti bölmek zordur. Modülleri net olan bir monolitte ise bir modülü ayırmak sınırlı bir iştir. Zor olan bölmek değil, baştan düzeni korumaktır.

"Büyük şirketler mikroservis kullanıyor." Doğru, çünkü yüzlerce geliştiricileri ve o ölçeğin sorunları var. Onların çözümünü kendi sorununuz olmadan almak, yalnızca maliyetini almaktır.

"Yatırımcı ya da teknik danışman sorar." İyi bir yanıt, moda bir mimari değil, gerekçeli bir karardır: neden böyle başladınız ve hangi ölçüm sizi değiştirmeye götürür.

Ekip büyüdüğünde ne değişir?

Mikroservislerin gerçek faydası teknik değil, örgütseldir. Birkaç ekip aynı kod tabanında çalışmaya başladığında birbirinin yayınını beklemeye, birbirinin değişikliğini bozmaya başlar. O noktada sınırları net olan modüller, ayrı ekiplere ve gerekirse ayrı servislere dönüşebilir.

Bu geçişin doğal bir sırası vardır: önce modül sınırları, sonra modül başına sorumlu ekip, en son ayrı yayın. Sırayı tersinden uygulamak, yani önce servislere bölüp sonra sınırları aramak, en pahalı yoldur.

En zor kısım veridir

Mikroservislere geçişte kodu bölmek görece kolaydır. Zor olan veriyi bölmektir. Tek bir veritabanında iki tablo arasındaki ilişki tek bir sorguyla okunur ve tek bir işlemle güncellenir. Veri iki servise ayrıldığında aynı ilişki ağ üzerinden kurulur.

Bu yüzden modüler bir monolitte asıl disiplin veri tarafındadır: her tablonun sahibi olan bir modül vardır ve başka modüller o tabloya doğrudan sorgu atmaz. Bu kural bugün gereksiz bir kısıt gibi görünebilir. Bir gün bir modülü ayırmanız gerekirse, işin ne kadar süreceğini bu kurala ne kadar uyduğunuz belirler.

Özet

Erken aşamada çoğu ürün için doğru başlangıç modüler bir monolittir: tek uygulama, net iç sınırlar. Mikroservisler birçok bağımsız ekibin ve farklı yük profillerinin sorununu çözer; bedelini ise ilk günden ister. Bir parçayı tahmine göre değil, ölçülen bir ihtiyaca göre ayırın.

İlk sürümün mimarisini birlikte kurar, kararları yazılı olarak bırakırız. Ayrıntılar MVP geliştirme sayfamızda.

OKUMAYA DEVAM

İlgili yazılar

Tüm yazılar

İşinizi anlatın.

Neyin yavaş ya da elle yürüdüğünü yazın, size ne yapılabileceğini söyleyelim.

Görüşme planla