5 puan yazan GN⁺ 2025-12-14 | 2 yorum | WhatsApp'ta paylaş
  • Twilio Segment, yüzlerce mikroservisten oluşan yapıyı işletirken karmaşıklık ve bakım yükü nedeniyle tek hizmete (monolitik) geçti
  • Başlangıçta her destination API’sini ayırarak hata izolasyonu ve ölçeklenebilirlik sağladı, ancak hizmet sayısı 140’ın üzerine çıkınca operasyonel overhead hızla arttı
  • Çok sayıdaki repository ve paylaşılan kütüphaneyi yönetmek zorlaştı ve test/dağıtım sırasında tüm hizmetleri etkileyen sorunlar ortaya çıktı
  • Bunu çözmek için Centrifuge sistemi ve monorepo yapısı devreye alındı, test otomasyonu için de Traffic Recorder geliştirildi
  • Sonuç olarak geliştirme hızı ve kararlılık önemli ölçüde arttı; Twilio Segment bugün üretkenlik ve operasyonel verimlilik için monolitik yapıyı koruyor

Mikroservislerin benimsenmesi ve sınırları

  • Twilio Segment, müşteri veri altyapısı için mikroservis mimarisini benimsedi; her amaca özel hizmet bağımsız olarak event işleyecek şekilde tasarlandı
    • Yüzlerce server-side destination’a (ör. Google Analytics, Optimizely vb.) veri iletildi
    • Başlangıçta tek bir kuyruk kullanıldı, ancak belirli bir destination arızalandığında tüm sistemde gecikmeye yol açan head-of-line blocking sorunu ortaya çıktı
  • Bunu çözmek için her destination için ayrı hizmet ve kuyruk oluşturuldu; böylece hata izolasyonu ve bağımsız ölçekleme sağlandı
  • Ancak hizmet sayısı arttıkça operasyonel karmaşıklık ve bakım maliyeti hızla yükseldi; bu da geliştirme hızının düşmesine ve hata oranının artmasına yol açtı

Ayrı repository’ler ve paylaşılan kütüphanelerin sorunları

  • Her destination farklı API formatları kullandığı için özel dönüşüm kodu gerekiyordu
    • Başlangıçta bunlar tek bir repository’de yönetiliyordu, ancak test başarısızlıkları herkesi etkilediği için repository ayrımı yapıldı
  • Sonrasında 50’den fazla yeni destination eklenince 50’den fazla repository ortaya çıktı
    • Ortak işlevler için paylaşılan kütüphaneler kullanıldı, ancak sürüm uyumsuzlukları ve dağıtım yükü büyüdü
  • Hizmetlerin yük desenleri farklı olduğundan otomatik ölçekleme ayarları zorlaştı ve bazı durumlarda operatörlerin elle müdahalesi gerekti

Monolitik dönüşüm ve Centrifuge’un devreye alınması

  • 140’tan fazla hizmetin tek bir hizmette birleştirilmesine karar verildi
    • Ayrı kuyrukların yerine tüm event’leri tek hizmete ileten Centrifuge sistemi geliştirildi
    • Centrifuge daha sonra Twilio Segment’in Connections backend altyapısına dönüştü
  • Tek hizmet yapısına geçişle birlikte operasyonel yükün azaltılması ve arıza müdahalesinin sadeleştirilmesi sağlandı

Monorepo ve test otomasyonu

  • Tüm destination kodu tek bir repository altında birleştirildi ve 120’den fazla bağımlılık tek sürümde standartlaştırıldı
    • Sürüm yönetimi sadeleşti ve bakım verimliliği arttı
  • Test otomasyonu için Traffic Recorder devreye alındı
    • Gerçek HTTP istek ve yanıtları kaydedilip tekrar oynatılarak dış ağ bağımlılığı ortadan kaldırıldı
    • Test süresi dakikalardan milisaniyelere indi ve kararlılık büyük ölçüde arttı
  • Test başarısızlık oranı düştü, geliştirici üretkenliği belirgin biçimde iyileşti

Monolitik yapının etkileri ve trade-off’ları

  • Tek hizmete geçildikten sonra dağıtım hızı ve geliştirme verimliliği ciddi şekilde arttı
    • 1 yılda paylaşılan kütüphane iyileştirme sayısı 32’den 46’ya çıktı
    • Tek bir mühendis birkaç dakika içinde dağıtım yapabilir hale geldi
  • Operasyonel verimlilik de iyileşti; ani yük artışları büyük worker pool’larla karşılanabildi
  • Ancak hata izolasyonunun zorlaşması, cache verimliliğinin düşmesi ve bağımlılık güncellemelerinde risk gibi dezavantajlar da var
    • Bu kayıpların bir kısmı operasyonel sadelik ve üretkenlik artışıyla telafi edildi

Sonuç

  • Mikroservisler başlangıçtaki performans sorunlarını çözdü, ancak büyük ölçekli genişleme ve toplu güncellemeler için uygun değildi
  • Monolitik dönüşüm, hem operasyonel kararlılığı hem de geliştirme hızını iyileştirdi
  • Başarılı bir geçiş için sağlam bir test sistemi ve trade-off’ları kabullenme şart
  • Twilio Segment bazı altyapılarda hâlâ mikroservis kullanıyor, ancak server-side destination’lar için monolitik yapı daha uygun görülüyor

2 yorum

 
yangeok 2025-12-16

Her şeyi parçalara ayırıp normalleştirmek riskli gibi görünüyor.

 
GN⁺ 2025-12-14
Hacker News görüşleri
  • Tüm hedeflerin kodunu tek bir repo içinde toplayınca, bunları tek bir hizmette birleştirebildiler
    Sonuç olarak geliştirme verimliliği büyük ölçüde arttı. Artık paylaşılan bir kütüphanede her değişiklik yaptıklarında 140'tan fazla hizmeti dağıtmaları gerekmiyor
    Tek bir mühendis artık birkaç dakika içinde dağıtım yapabiliyor
    Eğer bir kütüphane değişikliği yüzünden tüm hizmetleri yeniden dağıtmanız gerekiyorsa, bu gerçek bir hizmet değil, dağıtık monolitik yapıdır
    Paylaşılan kütüphaneleri tüm hizmetlerde zorunlu olarak senkronize etme fikri, hizmet mimarisi felsefesiyle baştan çelişiyor

    • Söylediğinde haklılık payı var ama pratikte durum çok daha karmaşık
      Bu, “her kütüphane güncellemesinde her şeyi yeniden dağıtmak”tan çok Amazon tarzı bir ortak build ve dağıtım sistemine benziyor
      Kütüphaneler merkezi olarak yönetilen tek bir kaynaktan alınıyor ve sürümler farklıysa uyumluluk sorunları nedeniyle herkesin migration yapması gerekiyor
      Güvenlik açığı nedeniyle belirli bir sürümü kaldırmak gerektiğinde toplu yeniden dağıtım gerekebilir, ama merkezi yönetimin faydası çok daha büyük
      Bu tür sistemler hâlâ mikroservis olarak sınıflandırılır, ancak maliyet ve operasyonel verimlilik açısından paylaşımlı bir ortam gibi çalışır
      Buna dağıtık monolit demek aşırı bir yorum olur
    • Söylemesi kolay ama pratikte hizmetler arasında ince hatalara ve uyumsuzluklara yol açması çok kolay
      Mikroservis desenini izledikçe dağıtım riski artıyor ama başta bu pek görünmüyor
      Örneğin para ile ilgili bir kütüphanedeki hatayı düzelttiyseniz, gerçekte tüm hizmetleri yeniden dağıtmanız gerekip gerekmediğini sorgulamaya başlarsınız
    • Bir kütüphaneyi sistem genelinde yükseltmek zorunda olmak mutlaka yanlış bir bağımlılık olduğu anlamına gelmez
      Güvenlik açığı olan bir kütüphane, sistem tasarımından bağımsız olarak tamamen değiştirilmelidir
      Böyle durumlarda monolitik yapı aslında daha kolay yönetilir
    • Paylaşılan kütüphane kavramının kendisi tüm hizmetleri zaten sıkı şekilde birbirine bağlar
      Gerçek mikroservislerde hizmetler mesaj alışverişi yapmalı ve JSON kullanmalıdır
      Kodun kendisini değil yalnızca API'yi bilmek yeterli olmalıdır. Ancak o zaman herkes bağımsız olarak dağıtım yapabilir ve ölçeklenebilir
    • O zaman 140 hizmetin her birine logging kodunu baştan mı yazmak gerekiyor?
      Paylaşılan modüller kullanmak daha mantıklı değil mi?
  • Önceki şirketimde her şey mikroservis olarak çalışıyordu, ondan önceki şirkette ise AWS serverless vardı
    Her iki durumda da en büyük sorun hizmetler arası iletişimdi. Sözleşmeleri (contracts) senkronize etmek zordu ve dağıtımlar da karmaşıktı
    Başlangıçta hızlı ilerliyorduk ama zamanla karmaşıklık patladı. Korkuya dayalı geliştirme ortaya çıktı ve toplantılar aşırı arttı
    Şu anki şirketim monolitik yapı kullanıyor ve yönetmesi çok daha kolay. Tipler net, refactoring basit
    Kendi platformumuz üzerinde kurulu yapay zeka ajanlarının kod tabanı içinde kendilerini iyileştirdiğini görmek ilginç
    Tek dezavantaj uzun build süreleri ama araç zincirindeki gelişmeler sayesinde 2026'da 10 kat daha hızlı dağıtım bekliyorum
    Benim vardığım sonuç şu: monolitik yapı sayesinde çok daha hızlı büyüyebildik ve ölçeklenebildik

    • Benim deneyimim tam tersiydi. SendGrid'de 10 yıl çalıştım; ekip 12 kişiden 500 kişiye çıktı ve bu, hizmet mimarisi sayesinde mümkün oldu
      Monolitik yapıda sorumlulukların ayrımı sürekli bozuluyordu ve ekipler arası bağımlılık çok yüksekti
      Gerçek hız ve ölçek ancak ekipler ayrıştığında mümkün oldu
      ORM'den DTO'ya geçmek için 2 yıl, 50 ekip ve 150'den fazla kişi gerekti
      Bu kadar karmaşık bir iş, mikroservisler olmasaydı mümkün olmazdı
  • Bu yazıya bakınca, meselenin özü mikroservis vs monolitik gibi teknik bir tercih değil
    Asıl konu mühendislik organizasyonunun kalitesi ve yapısı
    Kod deposu ve test yapısı, organizasyonun seviyesini olduğu gibi yansıtıyor

    • Birçok ekipte yeterli teknik disiplin yok
      “Bunu yapmayalım” diyebilecek kimse yoksa karmaşıklık patlıyor
      Ekibin durup düşünmesini sağlayacak yetkili bir lider gerekli
    • Twilio projesinde birlikte çalıştım; gerçekten berbattı
      API sorunları çıktığında kök nedeni analiz etmek yerine sadece veriyi düzeltip ticket'ı kapatıyorlardı
      Aynı sorun tekrar etse bile temel neden çözülmüyordu
    • Conway yasası bir kez daha doğrulanıyor
      Sadece mülakat yaparak bile bir şirketin kod tabanının yapısını belli ölçüde tahmin edebilecek noktadayım
  • Bu aslında tam bir monolite dönüşten çok hâlâ bir SOA yapısı
    Sadece hizmetlerin kapsamı büyümüş
    Eğer 140 hizmet tek bir ekip tarafından yönetiliyorsa, SOA hizmetleri ölçeklemek için değil ekipleri ölçeklemek için kullanılan bir yapıdır
    Tek bir ekip tüm paylaşılan kütüphaneleri yönetirse sürüm uyumsuzlukları ve API karmaşası ortaya çıkar
    Sonuçta mimariyi organizasyon yapısı belirler. Burada olan şey, tek bir ekibin karmaşıklığı azaltmak için sistemi birleştirmesi
    Bu “monolit” değil, ekip ölçeğine uygun şekilde kapsamı ayarlanmış bir hizmet seviyesi
    Bence en ideal yapı bu. Ekip büyüdüğünde tekrar ayrılması gerekir

  • Mikroservis savunucusu değilim ama “monorepo vs mikroservis” şeklindeki sahte ikilik göze çarpıyor
    Çok fazla araç, hizmet ile repo arasında 1:1 ilişki varsayıyor
    Oysa her şeyi tek bir repo içinde tutup yine de bağımsız dağıtım yapmak mümkün
    GitHub gibi yerlerde bunu klasör bazında bağımsız hizmetler olarak ele alabilmek güzel olurdu

    • Önceki şirketimde bunu bizzat kurduk
      Bazel ile bağımlılık ağacını yönettik ve bazel query ile etkilenen target'ları bulup testleri otomatik çalıştırdık
      GitHub Actions ile entegre ederek PR'ları engelleyen bir iş akışı oluşturduk
      İyi çalıştı ama kurulumu aylar sürdü
    • “Mikroservisten monolite geçince sorunlar ortadan kalktı” sözü rahatsız edici
      Gerçek sorun aslında operasyon ve araç eksikliğiydi — CI, auto-scaling, on-call düzeni; hepsi yetersizdi
  • Her iki yaklaşım da başarısız olabilir
    Node.js veya Python gibi ortamlarda event loop'un kaldırabileceği kod miktarının bir sınırı var
    6-8 kişinin 200 hizmet yönettiği de oldu, 80 kişinin tek bir monoliti yönettiği de
    Mikroservisler küçük değişikliklerde avantajlı ama sistem çapındaki değişikliklerde zorlayıcı
    Monolitik yapı ise bunun tam tersi
    Sonuçta önemli olan mimarinin kendisi değil, soyutlama, test ve gevşek bağlılık yöntemleri

    • “Tek bir iş problemini çözen bir yazılımsa, bunu tek bir mikroservis olarak paketlemek gerekir”
      Mikro olmanın ölçütü teknoloji değil, iş birimidir
      Bunun daha altına inerseniz nanoservis olur
    • Bu tür gerekçelendirmeler bana sonuçta sadece runtime sınırlamalarını örtmek için kullanılan geçici çözümler gibi geliyor
      Beam, JVM, Rust, Go gibi ortamlarda bu zaten çözülmüş bir sorun
    • Event loop'un kaldırabileceği kod miktarı sınırı derken tam olarak hangi ölçü biriminden söz ediliyor merak ediyorum
      Bu bir CPU cache meselesi mi?
    • Büyük ölçekli ortamlarda gerçekten Node.js veya Python kullanılıyor mu emin değilim
      Genelde Go, Java veya C# kullanıldığını sanıyordum
  • Çoğu şirkette mikroservisler aslında sorunların %90'ının kaynağıydı
    AWS, Google, Netflix gibi dev organizasyonlar değilseniz uygun değil
    Sistemi baştan birleştirilebilir parçalara ayırmak zaten yeterince zor; üstüne bir de ağ sınırları eklemek akıllıca değil
    Bir sonraki trendin React ve SPA'den uzaklaşıp sunucu merkezli yapıya dönüş olacağını düşünüyorum

  • Mikroservislere geçiş gerekçesinin “testler sık sık bozuluyordu” olması, bana çok ters bir yaklaşım gibi geliyor
    Testler bozuluyor diye kod tabanının yapısını tamamen değiştirmek garip

    • Biz de benzer bir sorun yaşadık ama çözümü her ekibe bağımsız bir geliştirme ortamı vermekte bulduk
      Ekip bazında ayrı VM'ler ve CI/CD ayarları tanımlayınca test çakışmaları ortadan kalktı
      Dezavantajı, özellikler arası çakışmaları anında fark edememekti ama kod sahipliği net olduğu için büyük bir sorun olmadı
  • Başlığa [2018] eklenmesi yönünde bir istek vardı

    • Acaba şimdi yeniden mikroservislere geri dönüş mü yaptılar diye merak ediyorum
    • 7 yıl önceki bir yazının tekrar gündeme getirilmesini pek doğru bulmuyorum. Teknoloji dünyasında bu neredeyse antik tarih sayılır
  • “Testler bozulunca alakasız kodları da düzeltmek zorunda kalıyorduk” diye repo'ları ayırmışlar ama,
    testlerin çalıştırılma şeklini değiştirmek ya da manuel dağıtıma izin vermek gibi başka çözümler de olabilirdi
    Repo ayrımı tek çözüm değildi