Microservice Mimarisi ile Yazılım Tasarımı

Gökhan Ayrancıoğlu
8 min readNov 12, 2019

Bir microservice mimarisinin tasarımı nasıl olmalıdır, hangi yapılardan oluşuyor, olmazsa olmazları nelerdir’ sorularını cevaplayalım.

Microservice Mimarisi makale serisinin önceki yazılarından, microservice mimarisi hakkında temel edinebilirsiniz. Bu makalede, microservice mimarisinin backend özelinde derinliğine inerek gerçek bir uygulamadaki halini öğrenebilirsiniz.

Microserviceleri kullanarak bir uygulama oluşturmadan önce, uygulamanızın kapsamı ve işlevlerinin iyi belirlenmiş olması gerekmektedir. Bu, tüm özellikleri ön görmeniz gerekiyor anlamına gelmez. Uygulamanın şu anki isterlerini ve yapılacak işleri bilmeniz anlamına gelmektedir ve bunları geliştirirken microservice mimarisi gerekirse yeni özellikler eklenebilmesini kolaylaştıracaktır.

Bir microservice nasıl olmalıdır sorusunun cevabını daha önceki yazılarda özetlemiştik, ancak bir kez daha üstünden geçmekte yarar var.

  • Her servis birbirinden bağımsız geliştirilebilir ve komplekslikten uzak olmalıdır.
  • Her servis kendi kod yapısına sahip olmalı ve küçük takımlar tarafından geliştirilebilir yapıya sahip olmalıdır.
  • Her servis kendi işine, görevine odaklı tek bir işlevselliğe hitap etmelidir. Tasarlanan her microservice, uygulamanın sadece bir modülüne odaklanacaktır.
  • Her service kendi için en iyi teknoloji altyapısını kullanabilmelidir. Tek bir teknoloji altyapısına bağımlı olmamalıdır. Yani, bir servis Java Spring ile yazılırken diğer servis Go yada Scala dilinde geliştirilebilir.
  • Her servis kendi DevOps planını içermeli ve kendi versiyonları olmalıdır. Uygulamayı, her bir servisin ayrı ayrı dağıtılabileceği şekilde tasarladığınızdan emin olmalısınız. Her servis deploy edildiğinde bağımsız bir şekilde kendi yöntemlerini kullanabilmelidir.
  • Servisler arası iletişim iyi tanımlanmış olmalı ve yeni adapte edilebilecek servisler tarafından da algılanabilir olmalıdır. Yeni servisin eklenmesi olabildiğince diğer servisleri bağımlılık ya da değişiklik açısından etkilememelidir.
  • Her servis kendi sorumluluğundaki veriyi saklamalı ve işlenmiş verileri gerektiğinde dışarıya verebilecek bir durumda olmalıdır. Her servisin kendine ait veritabanı olmalıdır. Bir service Nosql kullanırken diğer biri Sql database kullanabilir. Diğer bir deyişle, bir servis Mongodb kullanırken diğeri ihtiyacına göre Cassandra kullanabilir.
  • Microserviceler arasındaki iletişimin stateless bir sunucu üzerinden yapılmalıdır. Bazı haberleşmeler için message bus kullanılabilir.

Microservice mimarisi için operasyonel anlamda yapabilecekler nelerdir ?

  • Servis çoğullama: Gerektiğinde kolayca scale olabilecek bir sistem oldukça önemlidir. Microservice’in temel görevlerinden biridir. Çeşitli e-ticaret sitelerinin indirim dönemindeki yoğunluktan dolayı hizmet verememesinin başlıca nedenlerinden biri bu maddenin yeterince iyi yapılmamasından kaynaklanmaktadır.
  • Servis discovery: Servislerin kendi aralarında iletişim kurabilmeleri için ip, servis ismi gibi iletişim bilgilerini servis discovery’e kaydeder. Böylece bir servis diğeriyle iletişim kurmak istediğinde ip adresini bilmek zorunda kalmaz, sadece ismi ile servis discovery servisinden tüm iletişim bilgilerini öğrenebilir. Böylece değişken ip adresi ve iletişim bilgilerinden etkilenmeden sadece servis ismi ile iletişim kuracağı servisin bilgilerine ulaşabilir.
  • Servis izleme ve loglama: Sistem içerisinde microservicelerin loglarını izleyip, raporlayabilecek bir yapı içermelidir. Servislerde neler olup bittiğini, akan trafiği ve oluşan sorunları analiz etmek için kullanılabilir.
  • Hata Durum Yönetimi: Servislerden oluşabilecek hatalar karşısında otomatik olarak uygulanacak yöntemleri içeren mekanizmadır.
  • DevOps: Continuous integration ve deployment (CI ve CD) mekanizması. Servislerin birbirinden bağımsız olarak, istemcileri ya da kullanıcıları etkilemeden yönetilebilen bir deployment mekanizmasıdır.
  • API Gateway: Clientlar üzerinden gelen istekler için tek giriş noktası olarak kullanırlar.

Şimdi microserviceleri tasarlarken temel yönergeleri okuduğunuza göre, microservicelerin mimarisini anlayalım.

Microservice Mimarisi için kullanılan yöntem ve design patternler

Microservice mimarisi; farklı cihazlardan gelen farklı istekleri (arama, oluşturma, yapılandırma ve diğer işlemler) farklı servisler üzerinden yönetmeye odaklanır.

Her bir modül, kullanım amacı ve işlevselliklerine göre ayrılır ve ayrı birer microservice haline getirilir. Bu microserviceler, fonksiyonlarını yerine getirmek için kendi load-balance ve uygulama ortamlarına sahiptir ve aynı zamanda kendi veritabanlarında veri saklayabilirler.

Tüm microserviceler birbiriyle stateless olarak REST ya da bir MessageBus üzerinden iletişim kurar. Microserviceler, Service Discovery sayesinde iletişim kuracakları servislerin iletişim bilgilerine ulaşabilir ve servislerin durumlarını da izleyebilirler.

Clientlar tarafından oluşturulan tüm istekler API Gateway aracılığıyla microservicelere iletilir. Böylece microservice kendi görevlerini yerine getirerek gerekli cevabı geri dönebilirler.

Microservice Mimarisi

Bir microservice mimarisi özetle aşağıdaki yapıları içermelidir:

  1. Clientlar
  2. API Gateway
  3. Servisler arası iletişim( Rest, Message Bus )
  4. Veri Saklama ve Database Yapısı
  5. Servis Yönetimi
  6. Servis Discovery
  7. Loglama ve İzleme
  8. Devops
  9. Dahası

1. Clientlar

Farklı clientlara hitap edebilen bir mimaridir. (image source)

Microservice mimarisi, farklı istemci türleriyle başlar, farklı aygıtlar client olarak nitelendirilebilir. Client kullanıcının gördüğü arayüzlerle server side iletişimini sağlar. Aynı yapıda farklı tip clientlar mevcut olabilir. Tarayıcılar üzerinde çalışan web kısmı, mobilar kısımda çalışan android ve ios gibi nitelendirilebilir. Clientların asıl önemsediği kısım backend’e istekte bulunarak istenilen verinin kullanıcılar tarafından yönetilebilmesini sağlamaktır. Bunun için de oluşturma(CRUD), görüntüleme, silme, güncelleme, yapılandırma, veri işleme vb. gibi çeşitli işlevlerin backend kısmı tarafından gerçekleştirilmesini isterler.

2. API Gateway

Bütün servisler için tek giriş kapısı (image source)

Clientlar microservicelere doğrudan erişmez. API Gateway, clientların isteklerini uygun microservicelere iletmek için bir giriş noktası görevi görür.

API Gateway kullanmanın avantajları:

  • Tüm servisler clientların haberi olmadan güncellenebilir.
  • Servisler kendi aralarındaki iletişimler için arka planda clientlardan bağımsız olarak istenilen mesajlaşma protokollerini kullanabilir.
  • API Gateway, güvenlik, authentication, authorization ve load-balance gibi ek sorumlulukları da yerine getirebilir.

Clientlardan gelen isteklere cevap verebilmek adına, iç mimaride microserviceler, isteği yerine getirmek için kendilerine düşen görevleri birbirleriyle iletişim kurarak gerçekleştirebilir.

Bir API Gateway’in her zaman yüksek oranda erişilebilir ve performanslı bir bileşen olması gerektiğine dikkat etmelisiniz çünkü tüm sistemin giriş noktasıdır.

Clientlardan gelen tüm istekler önce API Gateway üzerinden geçer. Daha sonra istekleri uygun microservicelere yönlendirir. HTTP ve WebSocket gibi web protokollerini içeride kullanılan farklı protokollere de çevirebilir. Amaca göre her farklı tipteki client’a özel API oluşturabilir.

3. Servisler arası iletişim( Rest, Message Bus )

Microservicelerin birbirleri arasında iletişim kurdukları iki tür mesajlaşma yöntemi vardır:

(image source)
  • Eşzamanlı Mesajlar: Clientlar bir isteğin yanıtını beklediği durumda, microserviceler genellikle HTTP protokolünü kullanarak Rest haberleşirler. Bu protokol her biri dağıtık bir şekilde konumlanan ve tek görevi olan microserviceler için kullanılan ve bir servisin bir diğer servisten bilgi veya veri işlemesine ihtiyacı olduğunda o servise istek yaparak işlemin gerçekleşmesi sonucu cevabını alır ve kendi işlemlerini gerçekleştirdikten sonra client’a cevabını döner.
  • Eşzamansız Mesajlar: Clientların bir servisten yanıt beklememesi durumunda ya da bir microservicede yapılan işlem hakkında, diğer microserviceleri bilgilendirmek amacıyla; microserviceler genellikle AMQP, STOMP, MQTT gibi protokolleri kullanarak message buslar aracılığı ile tek yönlü iletişim kurabilirler.

4. Veri Saklama ve Database Yapısı

Her bir microservice verilerini saklamak ve ilgili veritabanı işlemlerini uygulamak için özel bir veritabanına yani kendi için en uygun veritabanına sahip olmalıdır. Her bir microservice farklı veritabanı yönetim sistemi kullanabilir, aynı zamanda aynı sistemi kullansa bile her biri ayrı ayrı kendi veritabanına sahip olmalıdır. Örneğin bir servis Mongodb kullanırken diğer serviste MongoDb kullanabilir ama her biri kendi mongo instance’ına sahiptir. Yani bir veritabanındaki kesinti diğer microservice’i etkilememelidir.

Her bir microservice farklı veritabanı yönetim sistemi kullanabilir, yani bir servis MongoDb kullanırken diğer biri Cassandra kullanabilir. Bu kesinlikle o servisin ihtiyacına göre şekillenir. Ancak çok çeşitli olması databaseleri yönetmek içinde maliyet çıkarabilir. Bu yüzden en optimuma yönelmek gerekir.

Bir diğer önemli nokta ise, microservicelerin veritabanları sadece servis API’leri aracılığıyla güncellenir. Direkt olarak database işlemi yapılmamalı, yapılamamalıdır. Bir verideki güncelleme diğer servisleri etkileyebilir. Bu yüzden veritabanı üzerindeki her işlem microserviceler aracılığıyla yapılmalıdır.

5. Servis Yönetimi

Microservislerden oluşan bir sistemi yönetmek için her bir servis ile ilgili tüm bilgileri tek bir merkezi yerde toplamak gerekir. Böylece, microservice kümesinde çalışan tüm uygulamaların durumuyla ilgili bilgileri ve ayrıntıları anlık olarak tek bir ortamdan izleyebilir, raporlarını görebilir ve yönetebilir oluruz. Böylece oluşabilecek sorunlara müdahale edebiliriz.

Microserviceler, konteyner teknolojilerine uyumlu bir şekilde birlikte çalışır. Konteynerlar tercih edilir çünkü kendileri yeterlidir ve hızlı bir şekilde hazır hale gelir veya klonlanabilir. Bir microservice projesinde her bileşen parçası docker kullanılarak dinamik olarak yönetilmektedir.

Mikroserviceler ile bütün konfigüre edilebilir servis parametrelerinin merkezi bir konfigürasyon yönetiminde ayarlanabildiği, versiyon kontrolü yapıldığı ve yönetildiği bir merkezi konfigürasyon sunucusu içermelidir. Merkezi bir yapılandırma sunucusunun yararı, bir microservice için bir özelliği değiştirirsek, microservice yeniden dağıtılmadan bunu anında o servise yansıtabiliriz.

6. Servis discovery

Düğümlerin bulunduğu hizmetlerin bir listesini tutarken, aralarındaki iletişim yolunu bulmak için microservicelere kılavuzluk eder.

Şimdi bu mimariyi ne zaman kullanacağınızı daha iyi anlayabilmek için bu mimarinin artılarını ve eksilerini inceleyelim.

Microservice mimarisinde, farklı IP’lerde ve bağlantı noktalarında çalışan birçok microservice bulunur ve normalde bunlar ile tek tek uğraşmak gerekir. Neyseki her bir ip adresi ile ilgili bir geliştirme olmadan yönetmenin bir yolu var. Service discovery ile her bir servis, bir client gibi kendini discovery server’a kayıt eder. Böylece ip’si ve ismi orada kayıtlı hale gelir. Bir servis diğer bir servise erişmek istediğinde ilk olarak discovery servisten istek atarak istediği servisin bilgilerini çeker ve böylece herhangi bir ip ya da port değişikliğinden etkilenmez.

7. DevOps

DevOps microservice mimarisi için olmazsa olmaz adımlardan biridir. Otomatize bir deployment sistemi ile her bir microservice için yeni bir versiyon çıkıldığında, kullanıcılar etkilenmeden bu güncelleme gerçekleştirilebilir.

Her microservice, herhangi bir sürümü herhangi bir ortama otomatik ve güvenilir bir şekilde deploy edebilme özelliğine sahip olmalıdır. Dağıtımı tamamen otomatik ve basit tutmak, küçük değişiklikleri sık sık güvenle deploy etmeyi kolaylaştırır.

Dahası

Microservice mimarisine uygun bir mimari tasarlamanın altın kuralı servisleri en doğru ve optimum şekilde ayırabilmektedir. Bottleneck oluşturabilecek hiçbir servis olmamalıdır. Servislerin birbirine bağımlılıkları en aza indirgenmelidir. Servisler arası iletişimde Rest yerine olabildiğince message bus ile işlemler gerçekleştirilmeli böylece bağımlılıklar azaltılmalıdır.

Api gateway uygun bir çözümdür, ancak tek giriş noktası olduğu unutulmamalı ve buna göre deploy edilip yönetilmelidir. Giriş noktası olduğu için Authentication ve Authourization mekanizmaları burası üzerinde konumlandırılabilir. Servislerin sağlıklarını izlemek önemli bir noktadır, oluşabilecek risklere karşı her zaman hazır ve otomatize önlemler alınmalıdır. Loglama mekanizması kritik öneme sahiptir, veri akışını ve oluşabilecek hataların tespitini kolaylaştırır.

--

--

Gökhan Ayrancıoğlu

Software Engineer @Yemeksepeti • #Java • #Spring Boot • #Kotlin • #Spark • #Microservices • https://gokhana.dev