SPRING BOOT İLE MICROSERVICE REGISTRY VE DISCOVERY PATTERNLERİNE BAKIŞ

BilgehanYıldız
4 min readSep 23, 2021

--

Microservisler kullanımı ile alakalı olarak artılarına baktığımız zaman en büyük artılarından biri kolayca yük altında arttırılıp azaltılabilen yapılar olması olarak görürürüz.Tabi bu dinamiklik beraberinde altyapısal olarak daha karmaşık olan yapılara yol açmaktadır.Bu yazımızda bu altyapısal karmaşıklıklarda microservislerin birbirlerin yerlerini bulmaları için yöntemleri ele alıyor olacağız.

Genel kavramlara baktıktan sonra bunların spring boot üzerinde örneklerinin nasıl olacağını bakıyor olacağız.

SERVICE Discovery Nedir?

Bir micro servis diğer microservise erişim sağlayabilmek için onun network üzerindekini yerini bilmek zorundadır.

Service Discovery temel olarak 3 kavram üzerinde durur

1-)Discover:Microservislerin http levelda haberleşebilmeleri için birbirlerinin ip ve port bilgilerini bulma yöntemleridir.

İki tip Discovery Pattern vardır

· Server Side Discovery:Burada client ile hizmet alacağı microservisler arasında bir load balancer mevcuttur.Client isteği loadbalancera yapar.Hizmet verecek microservisler ise loadbalancerın registrysine kayıt olur.Daha sonra loadbalancer ilgili isteği hizmet sağlayan microservise gönderir.Clientside discovery göre avantajı hizmet almak isteyen ve vermek isteyen microservisler arası direkt bir bağlantı olmayıp iki tarafta sadece loadbalancerı bilmektedir.

· Client Side Discovery:burada client hizmet alacağı servisin yerini bulmak ve atacağı istek için nasıl bir loadbalance yöntemi kullanacağından sorumludur.Öncelikli olarak service registry gidip hangi instanceların ayakta olduğu bilgisini elde eder.Daha sonra ise hizmet almak istediği instance isteği gönderir.

Şekiller ve daha fazla açıklama için

https://www.nginx.com/blog/service-discovery-in-a-microservices-architecture/

2-)Load Balancing:Bir istek geldiği zaman gelen istediğin ne şekilde dağıtılacağını belirler.Cluster yapılarda eğer arka planda down olan instancelar varsa bunların yük almasını engeller

3-)Health Check Servisi:Hizmet sağlayan bir microservisin ayakta olup olmadığı bilgisini registry ile paylaşabilmesine sağlayan yöntemdir.Bu sayede registry eğer health check bilgisi alamaz ise buraya istek göndermeyi engelleyebilir.

SERVICE REGISTRY Nedir?

Bir servis bir diğer microservisin yerini tespit edebilmek için client side discovery veya serverside discovery yöntemlerinden birini kullanmaktadır.Dolayısıyla microservislerin yerini tutup gelen isteklerinin nereye gideceğini belirleyecek yapılara ihtiyaçlar vardır.

Burada örnek olarak Netflixin Eureka serverı bu yapıyı bize client side discovery için sağlayan toollardan biridir.

Öteki tarafta nginx ise server side load balancer olarak kullanabileceği için server side discovery amacıyla kullanılabilir.

Spring boot ile ClientSide Discovery Örneğimiz için 3 adet microservis oluşturacağız

1-)Service Registry EurekaServer

2-)Provider MicroService

3-)Consumer Microservice

1-)Service Registry EurekaServer

ilk etapta service registrymizi ayaklandıralım eureka server

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>

<version>3.0.4</version>
</dependency>

Ve bazı versiyonlar için java 11 ile kullanıldığında jaxb-runtime eklemek gerekebilir

<groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId></dependency>

Daha sonra spring starter classımızın tepesine @EnableEurekaServer annatosyanonu koyuyoruz

@EnableEurekaServer@SpringBootApplicationpublic class EurekaserverApplication {   public static void main(String[] args) {      SpringApplication.run(EurekaserverApplication.class, args);   }}

En son application.properties dosyamıza aşağıdaki ayarları ekleyip

server.port=8091eureka.client.register-with-eureka=falseeureka.client.fetch-registry=falseeureka.instance.hostname=myserviceregistry

projemizi çalıştırarak service registry mizi ayağa kaldıyoruz

2-)Provider MicroService

Spring initializerda 2 adet dependency seçiyoruz eurekaclient ve healthcheck için spring actuator

Pom dosyamız

<dependency>   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency>   <groupId>org.springframework.cloud</groupId>   <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>

//Eurekada gözükecek uygulama adı

spring.application.name=providerservice//Eureka dan ara ve register ol ayarlarıeureka.client.register-with-eureka=trueeureka.client.fetch-registry=trueeureka.client.enabled=true//Eureka server url sonunda eureka eklenmelieureka.client.serviceUrl.defaultZone=http://localhost:8091/eureka

Bu ayarlardan sonra start ettiğimizde artık eureka serverda servisimizin register olduğunu görebiliyoruz.

https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html

Actuator ayarlarının detaylarına yukarıdaki linkten bakılabilir

http://localhost:8080/actuator/health

Actuator servisini aktiflemek için application.propertiese aşağıdaki parametreleri ekliyoruz

management.endpoints.web.exposure.include=*management.endpoints.health.show-details=alwaysmanagement.endpoints.jmx.exposure.include=*

3-)Consumer Microservice :burada dependecy olarak yine actuator ve eureka client kütüphaneleri ekliyoruz projemize

Eğer bu uygulamamızda eureka ya register olacaksa verilecek applicationnamein providerdan farklı olması gerektiğine dikkat etmek lazım.

server.port=8081spring.application.name=consumerserviceeureka.client.register-with-eureka=trueeureka.client.fetch-registry=trueeureka.client.enabled=trueeureka.client.serviceUrl.defaultZone=http://localhost:8091/eurekamanagement.endpoints.web.exposure.include=*management.endpoints.health.show-details=alwaysmanagement.endpoints.jmx.exposure.include=*

Consumer servisimizde yapmamız gereken ek iş olarak

DiscoveryClient paketi ile serviceregistryimiz olan eurekaya giderek gideceğimiz microservisin networkteki yerini öğrenmek gerekiyor.Daha sonra ise direkt olarak çağrım yapabiliyoruz(Client side discovery senaryosu).İstenirse burda yine netflix ribbon kütüphanesi yardımıyla client üstünde load balancing yapılabilir ancak bizim örneğimiz tek bir servis olduğu için kullanmadık.

package com.demo.consumerservice;import org.springframework.cloud.client.ServiceInstance;import org.springframework.cloud.client.discovery.DiscoveryClient;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.reactive.function.client.WebClient;import java.util.List;@RestController@RequestMapping("api/consumer")public class ExampleController {    @Autowired    private DiscoveryClient discoveryClient;    @GetMapping("callservice")    public ResponseEntity helloworld()    {        List<ServiceInstance> instanceList=this.discoveryClient.getInstances("PROVIDERSERVICE");        String BaseUri=instanceList.get(0).getUri().toString();        String path="/api/example/hello";        WebClient client = WebClient.create(BaseUri+path);        WebClient.ResponseSpec responseSpec  = client.get().retrieve();        String responseBody = responseSpec.bodyToMono(String.class).block();        return ResponseEntity.status(HttpStatus.OK).body("Çağırıldı"+responseBody);    }}

Çağrımızı yapıp cevabımızı almış oluyoruz

Kod örneklerine aşağıdaki urlden erişebilirsiniz.

https://github.com/BilgehanYildiz/SpringServiceRegistryDiscovery

--

--