Series B aşamasındaki bir girişim, bir keresinde mimari diyagramlarını gerçek bir gururla gösterdi: kırk üç mikroservis, bir servis ağı (service mesh), olay veri yolları (event buses) ve dahası. Sonra ödeme akışlarına bir değişiklik göndermenin ne kadar sürdüğünü sordum. Oda sessizleşti. Yanıt on bir gündü — çünkü tek satırlık bir fiyat değişikliği, dört ekibin sahip olduğu altı servise dokunuyordu ve birinin dağıtımları koordine etmesi gerekiyordu.
Aslında bir mikroservis mimarileri yoktu. Ellerinde, fazladan ağ çağrılarıyla donatılmış dağıtık bir monolit vardı ve bu, kaçtıkları kod tabanından değiştirilmesi daha yavaş bir şeydi.
Çözmeye çalıştığınız sıkıntı teknik değil, örgütseldir
Mikroservisler, özünde bir insan sorununun çözümüdür. Tek bir kod tabanında birbirinin ayağına basan çok fazla mühendisiniz olduğunda — birleştirme çakışmaları, birbirine bağlı dağıtımlar, kimsenin yavaşlatamayacağı bir yayın treni — sistemi bölmek, ekiplerin bağımsız biçimde sahiplenip dağıtım yapmasını sağlar. Kazanç budur. İnsanların öne sürdüğü diğer her şey (ölçekleme, dayanıklılık, çok dilli özgürlük) genellikle ikincildir ve çoğu zaman iyi yapılandırılmış bir monolit içinde de elde edilebilir.
Bu yüzden dürüst ilk soru "alan (domain) ayrıştırmasını nasıl yaparız?" değildir. "Mevcut mimarimiz gerçekten canımızı yakıyor mu ve nerede?" sorusudur. Sekiz mühendisiniz ve tek bir dağıtım iş akışınız varsa, mikroservisler size dağıtık sistem vergisi ekler — ağ arızaları, nihai tutarlılık (eventual consistency), dağıtık izleme, eskiden bir veritabanı işlemi olan şey için saga desenleri — ve faydanın neredeyse hiçbirini vermez.
Monolitinizin içinde bir modül sınırını temiz bir biçimde çizemiyorsanız, onu bir ağ üzerinden bölmek o sınırı ortaya çıkarmaz. Yalnızca dağınıklığı görmeyi zorlaştırır.
Gerçekten canınızı yaktığının işaretleri
Danışmanlık çalışmalarımda, herhangi bir bölünmeyi onaylamadan önce somut, ölçülebilir bir sıkıntı ararım. Önem taşıyan işaretlerden birkaçı:
- Dağıtım bağımlılığı. Bağımsız özellikler, aynı yayını paylaştıkları için bağımsız biçimde gönderilemiyor. Ekipler birbirinin arkasında sıraya giriyor.
- Birbirinden ayrışan ölçekleme ihtiyaçları. Tek bir bileşen — video dönüştürme, rapor üretimi, bir arama dizini — geri kalan her şeyin 20 katı kaynağa ihtiyaç duyuyor ve siz onu beslemek için tüm uygulamayı ölçeklendirmenin bedelini ödüyorsunuz.
- Etki alanı (blast radius). Nadiren kullanılan bir yönetici özelliğindeki bir bellek sızıntısı ödeme akışını çökertiyor, çünkü hepsi tek bir süreç.
- Ekip topolojisi. Beş ekibiniz ve tek bir kod tabanınız var ve koordinasyon maliyeti artık yol haritasında görünür durumda.
Bu listede olmayana dikkat edin: "Netflix'in bunu yaptığını okuduk" ya da "daha modern hissettiriyor." Bunlar işaret değildir. Bunlar modadır.
Önce sıkıcı işi yapın: modüler monolit
Ağa dokunmadan önce, mevcut uygulamanızın içindeki sınırları hak edin. Bir modüler monolit — açık arayüzlere sahip net modüller, başka bir modülün tablolarına uzanmama, tek yöne işaret eden bağımlılıklar — size mimari netliğin %80'ini, işletme maliyetinin %5'ine verir. Yine tek bir çıktı (artifact) dağıtırsınız. Yine tek bir veritabanı işlemine sahip olursunuz. Ama artık dikişler gerçektir.
Bu, çoğu ekibin atladığı en yüksek getirili hamledir. Ekibiniz o iç sınırları altı ay boyunca hile yapmadan koruyabiliyorsa, daha sonra çıkarma (extraction) neredeyse mekanik hâle gelir. Sınırı süreç içinde koruyamıyorlarsa, bir ağ üzerinde kesinlikle koruyamayacaklardır — yalnızca aynı karmaşaya gecikme ve yeniden denemeler ekleyeceklerdir.
Çıkarma yaptığınızda, her seferinde tek bir dikişten yapın
En net sınıra ve taşınmak için en güçlü bağımsız gerekçeye sahip modülü seçin — genellikle ayrışan ölçeklemesi olan ya da farklı bir ekibe ait olanı. Onu çıkarın. Canlı ortamda çalıştırın. İşletme yükünü hissedin: nöbet (on-call), gözlemlenebilirlik, dağıtım iş akışı, sözleşme sürümleme. Ardından bir sonrakinin buna değip değmediğine karar verin. Çoğu şirket, iyi seçilmiş üç ya da dört servisin faydanın neredeyse tamamını yakaladığını, geri kalan otuzunun ise yalnızca sıkıntı olacağını keşfeder.
Kimsenin sunuma koymadığı maliyetler
Bir mikroservis, onu oluşturduğunuz gün bedava değildir. Kalıcı bir yükümlülüktür: kendi CI/CD'si, kendi gösterge panelleri ve uyarıları, kendi gizli anahtarları (secrets) ve bağımlılık yükseltmeleri, nöbet dönüşümündeki kendi yeri. Bunu kırkla çarpın; ürününüzle hiçbir ilgisi olmayan, ikinci bir tam zamanlı iş kurmuş olursunuz.
Diğer sessiz maliyet hata ayıklamadır (debugging). Bir monolitte, bir yığın izi (stack trace) tüm hikâyeyi anlatır. Servisler arasında ise tek bir kullanıcı eylemi bir düzine sıçramaya yayılır ve gece 2'de, tek bir kesme noktasının (breakpoint) daha önce yanıtlayacağı bir soruyu yanıtlamak için günlükler boyunca korelasyon kimliklerini (correlation ID) birbirine dikersiniz. Bu gerçeğe göre bütçe ayırın ya da bu işe hiç girmeyin.
Pazartesi nereden başlamalı
Bir göç planlamayın. Dürüst bir denetim planlayın. Gerçek sıkıntıyı yazın — dağıtım süreleri, olayların etki alanı, koordinasyon kuyruğunda takılı kalan özellikler — her birinin yanına sayılar koyarak. Liste zayıfsa, yanıtınız dağıtık bir sistem değil, modüler bir monolit ve daha iyi bir modül disiplinidir.
Sıkıntı gerçek ve yerelse, tam olarak tek bir servisi, kanıtların işaret ettiğini çıkarın ve ikincisini çıkarmadan önce onunla yaşayın. Bırakın mimari, konferans konuşmasını değil, sıkıntıyı takip etsin.
Mikroservisler, belirli türde bir acı için bir araçtır. Onlara yönelmeden önce, canınızın nerede yandığını adlandırabildiğinizden — ve daha basit bir kesiğin bunu en az onun kadar iyi çözemeyeceğinden — emin olun.