Turknet Noctools Mühendislik Ekibinde bir mikro hizmet dönüşümünün hikayesi — teknik perspektif

Bilal İslam
TurkNet Technology
Published in
6 min readMay 17, 2022

Merhabalar ,

Daha önce business perspektifinden anlatmaya çalıştığım dönüşüm sürecinin bu sefer teknik taraftan ele almayı ve yaşadığımız deneyimi anlatmak istiyorum.

Öncelikle microservice dönüşümü için bir path’e ihtiyacımız vardı. Kabaca divide and conquer kolay gibi gözüksede seems adı verilen parçalar var. Yani eğer kumaşı nereden ayıracağınızı bilemezseniz zombi servisleriniz olabilir ve gün sonunda hiç bir amaca hizmet etmezler.

Özetle,clean code, testable code,ddd,12 factor derken aslında cloud native’e giden bir pramidin etrafında olduğumuzu anladık.

Clean Code

Görselde de görüleceği üzere önce clean code pratiklerini bilmek gerekiyor. Bunun için sonar-cloud’u kullandık. Ve her pr’in önünü sonar quality gateway’ini koyduk. Böylece fitness function olarak daha önce makalede belirttiğim üzere ekibin temel code standartlarını konusunda ki alignement’ı sağlamayı hedefledik. Test coverage’ı en az %80 olan servislerin hem bakımı kolay olur hem de üzerinde yeni fikirlerin denenmesi hızlı olacağı için yeni kazanımlara izin verir. Böylece lead time’ı artırarak production’a daha hızlı deliver yaparsınız.

Domain Driven Design

Domain driven konusuna gelince, aslında bu konu çok geniş bir prensipler topluluğunu kapsıyor ama biz her zaman ki gibi basit düşünmeyi hedefledik. Çünkü kompleks sistemlerde lean mindset’ini benimsemek önemlidir. Project based değil product based olarak değerlendirerek ve business around the world ve focus on the business not entity olarak Sam Newman ve Martin Fowler’ın söylediklerini düşünerek ilermek istedik.

Görselde lean development felsefemizin 5 adımı bulunmakta ve takip etmeye çalıştığımız yol genelde bu oldu diyebilirim.

Önceki makalede de değindiğim üzere event storming organizasyonel konuda benimde beklentim olurdu ama umarım en kısa zamanda böyle bir domain analiz pratiği oturturuz :)

Microservice

Microservice konusu ise eğer service optimized for change mindset’ini benimsemekten geçiyorsa o zaman mercedes şirketinin benimsediği gibi sık değişen parçalar dışarda nadir olarak değişenler ise içerde olmalıydı.

Bu konuda Vaughn Vernon ‘ın 3 chapter’dan oluşan effective aggregate design makalesi bulunmakta.

Modeling a Single Aggregate

Making Aggregates Work Together

Gaining Insight Trough Discovery

Ve bu makaleler aslında Implementing DDD’in en can alıcı noktalarından biri. Zaten kendisi de Aggregation Design’in DDD’de en az anlaşılan konuları olduğunu söylüyor olmasından belli ki konuyu damıtıp bu makaleleri yazmış.

Özetle bir microservice’in içi bu şekilde gözükmektedir. Diğer squad ekipleri veya kendi subdomain’imiz de yer alan servisler ile iletişimiz dışarda , aggregate’lerimizin birbirleri ile olan iletişimleri ise içerde yer almaktadır. Böylece geriye sadece domain’i business katmanda yöneten bir usecase manager’e ihtiyaç kalıyor.

Aynı noktada farklı yükler

Devraldığımız sistem 3 ayrı iş birimine 3 ayrı takım üzerinden bağlıydı. Yani işler bu zamana kadar el yordamıyla yapılıyordu. Tüm sorumluluk bir ürün takımına ait değildi.

Filmi başa sardığımızda aslında şunu farkettik;Multi tenant as a service modeline uygun SaaS bir ürüne ihtiyacımız var. Yani 3 ayrı ekibin isterlerini tek bir ürün karşılayacak . Bu da bizi isterlere göre bir ayrıma götürür. Her iş birimlerine göre bir data modeli design edilmeli ve event stream üzerinden bir api ile squad takımlarına verilmeliydi.

Bu verilere dayanarak, CQRS’yi Event Sourcing ile uygulamaya karar verdik. Bildiğiniz gibi, üç tip CQRS vardır.

Separated class structure, sınıfları ve okuma verilerini döndürmek için DTO’ları kullanan ayrılmış sınıf yapısı, bu da bazı yinelemelere neden olacaktır.

Separated model with different APIs Sırasıyla okuma ve yazma için farklı modellere ayrılmıştır. ( Optimize edilmiş sorgulara ek olarak bu, önbelleğe almayı da mümkün kılarak yüksek okuma yükleri için ilgi çekici hale getirir. )

Separated storage Okumaların daha da ölçeklenmesini sağlayan sorgular için optimize edilmiş yazma ve sorgulama için ayrı depolama türleri, ör. ilişkisel bir veritabanı ve bir NoSQL türü. Okuma deposunun senkronizasyonu genellikle arka planda çalışır ve okuma tarafında nihai tutarlılığa neden olur. En iyi ölçeklenebilirlik ile birlikte bu model aynı zamanda en yüksek karmaşıklığı da beraberinde getirir.

Bizim ise seperated class structure modelini servislerimiz iç yapısını design etmek için kullandık. Omurga ve müşteri cihazlarından gelen eventler için ise clustered timeseries olarak seperated storage kullandık. Aslında omurga cihazları birer mikroservice olarak düşünürsek , üzerlerinden gelen her event aslında bir projection’ı temsil ediyor. Bu eventleri build ettiğimizde ilgili müşteri cihazına ait tüm geçmişi izleyebiliyoruz. Özetle cqrs ‘i internal domain servislerimiz için kullanmış olduk , event sourcing için ise timeseries bir db üzerine event atmasını sağladığımız bir omurga network design ettik.

Böylece tüm cihazlar timeseries db’ye eventlerini atarken paralelde o projectionları build edip snapshot olarak iş birimlerinin ihtiyaçlarına göre zaman zaman bir rapor olarak , eğer journey ekiplerine vermemiz gerekiyorsa bir api olarak ya da agentlarımıza vermek üzere bir dashboard olarak vererek aslında noctools’a hit eden tüm takımlar için farklı farklı data modelleri elde etmiş olduk.

Bunun bize getirisi ise farklı yük vektörlerine göre bağımsız scalibility oldu.

Basit bir görsel ile anlatmak gerekirse ;

CQRS’yi Event Sourcing ile uygulamaya karar verdiğimizde web appleri üzerine çalışamayacağımızı biliyorduk. O yüzden network omurga cihazları üzerinden bu mimariye gitmenin bir yolunu aradık. Tabi TurkNet’in backbone topolojisi sürekli değişken bir yapıya sahip olduğundan db’lerden bağımsız bir şekilde bu süreçlerin yürümesi gerekiyordu.

O konuda bilgi vermem gerekirse , daha önceden kullanılan emektar cacti’nin miladı dolmuştu ve tüm icmp ve utilization süreçlerini single server setup olarak kendi içinde barındırıyordu. Sistemin değişen topology’e göre bağımsız scale olması için tüm data collectorlerin timeseries db’ye eventlerin atması gerekiyordu.

Sırasıyla ,

Zabbix > influx

Cacti > influx

Telemetry > influx

gibi tüm veriyi elinde bulunduran yazılımlar kendisine özel işleri yapıp verilerini cluster timeseries db’ye atması gerekiyordu ki infrastructure as code olarak provisioning yeteneğimiz stateless kalsın.

Bu sayede hem toolları istediğimiz gibi master ya da edge olarak konumlandırabileceğiz hem de tüm veriyi koruyup dolaylı olarak tabii bir Cqrs/Es mimarisi elde etmiş olacaktık. Yani en kompleks yapı olan event sourcing’in seperated stroge yöntemini toollara bırakacaktık. Tabi sistemlerin up time’larını ise sistem ve dba ekiplerimize vermiş olduk. Böylece network domain’inde ekibin sadece business logic’e odaklandığı ve ürünün altyapısından sadece altyapı ekibinin sorumlu olacağı bir yapıya evrildik.

Kaba bir hesap ile tam kapasite ile çalışan omurga cihazlar ile ;

8m user için 12m log

hafta da 84 m log

ayda 336 m log

yılda ise 4b log

Sauron, toplamda 4 milyar event’in scale edilmesini sağladığımızı düşündüğümüz bir ürün haline geldi.

Hedefimiz ise tam da buydu;

Cloud Native

Son olarak problemimiz ise tüm sistemleri cloud native olarak design etmemiz gerektiğiydi.

Bilindiği üzere cloud native olmanın 5 şartı var;

  1. open source
  2. microservice
  3. containerized
  4. orchestration
  5. optimum kaynak tüketimi

Bizimde izlediğimi yol bu oldu açıkcası . Şuan için deploy as a vm kullanıyoruz ama alt yapımız aslında deploy as a container ‘ı destekler vaziyette.

Derdimiz ise çok basit olarak gitops mindset’ine uygun servisler geliştirmekti. Yani geliştirdiğimiz her servis aynı zamanda k8s native de olmalıydı ki gitops olabilsin. Sauron şu an , gerekli infra çalışmaları tamamlandığında bu deployment mimarisine çok rahat evrilebilir durumda.

Language & Db Distribution

Asis Language ;

Tobe Language ;

Asis Db ;

Tobe Db ;

Teck Stack

Son olarak

Yine bir önce ki yazıda da olduğu gibi noctools ekibine bu özverili çalışmalarından dolayı sonsuz teşekkürlerimi borç bilirim.

Sauron be with you 🙂

--

--