Netflix Eureka Kullanarak Service Discovery Nasıl Uygulanır ?

Monolithic geliştirilen application'lar dan çıkıp Microservice mimarileriyle uygulamalar geliştirmeye başlayalı epeyce bir zaman oldu. Eskiden çokca muhtemel; tek bir solution, IIS'de host edilen tek bir Api ve bütün business'ın bu uygulamada olduğu yapılar tasarlarken bu uygulamayı consume edecek ekiplere tek bir ip adresi vererek hayatımıza devam ediyorduk.   

Günümüz yazılım dünyasına çokta uzak olmayan bir süre içerisinde zamanla Microservice mimarisiyle uygulamalar tasarlamaya,geliştirmeye başlamış olduk. Ancak bu da beraberinde bir sorun getirdi; o eskiden tek bir adreste host edilen api artık belki 10 farklı projeye bölünerek 10 farklı adreste farklı business'lar process edilerek host edilmeye başlandı. Bu microservice uygulamalarıda sürekli olarak birbirleri arasında httpCall'lar yaparak haberleşmesi ve bunun içinde her bir uygulama call edeceği application'nın host adresini bilip configSource'un da store etmesi gerekmekteydi. Tabi birde environment(test-prod) farklılıklarını yani x2 sayıda host adresi olması çok mümkün. Bu gibi sorunlara çözüm olarak service discovery kavramı karşımıza çıkıyor.

Yukarıdaki görsel nginx'in service discovery mimarisini anlatırken kullandığı bir görsel ve buna benzer sürekli olarak dynamic bir şekilde auto-scale olabilen ve yine aynı şekilde dynamic-ip-assign tanımlanabilen uygulamaları ele alacak olursak bu uygulamaları call eden client'lar sürekli olarak ipAddress'lerini bilmek zorundalar. İşte service discovery kavramı uygulamalar arası bu iletişimi host bilgisine gerek kalmaksızın yapabilmesini sağlayabilmektedir.

Service discovery; service'ler arası iletişim için uygulamaların birbirlerinin network adreslerini bulmasını sağlayan bir modeldir. Bu modeli uygulayabilmenin bir çok yöntemi bulunmaktadır ancak biz bu yazımızda ServiceRegistry ve ServiceRegistryClient'larından oluşan uygulamaların bulunduğu yapılara odaklanarak ne gibi çözümler getirebiliriz inceleyeceğiz.

Service registry;  bütün microservice instance'larının mevcutta host edildikleri network lokasyonlarını tutan merkezi bir bileşendir. 

Service registry client; microservice'ler tarafından registry'e kaydı bulunan ve network communication yapmak istediği service'in adresini registry'den sorgulayarak kullanırlar.

Projelerinize service discovery implement etmek için çeşitli tool'lar bulunmakta. Netflix Eureka, HashiCorp Consul, IstioZookeper etc.

Bu yazımızda Netflix Eureka kullanarak .net core uygulamaları için service discovery nasıl uygulanır inceleyeceğiz. 

Installing Eureka

Eureka; netflix yazlım ekibinin java tabanlı geliştirdiği bir service discovery-management tool'u dur. Çalışma mantığı olarak microservice'ler ayağa kalkarken service registry'e gidip kendi config dosyalarındaki key'lerle register olurlar ve yine herhangi bir microservice networkComm kurmak istediği service'in adresini bilmeksizin registry'e key bilgisi ile query yaparak aldığı value'u kullanarak iletişim kurmaya başlar.

 

Kurulum için Steeltoe ekibinin hazırladığı configurationFile'ları kullanarak çok basit bir şekilde eureka'yı docker'da ayağa kaldırabiliriz. Git adresinden ilgili dosyaları download ettikten sonra aşağıdaki komut ile birlikte localhost:8761 portunda Eureka server ayağa kalkacaktır. 

$ docker run --publish 8761:8761 steeltoeoss/eureka-server

Service Registry 

Eureka Server ayakta olduğuna göre artık microservice uygulamalarımızı geliştirebiliriz. Öncelikle vs'da bir blank solution açarak içerisine 2 farklı application ekleyelim. Bunlardan biri api olsun ve bir diğeri ise console app olsun. Eureka client iler register ettikten sonra consoleApp'in api uygulaması ile network comm. kurmasını sağlayalım. 

 

Steeltoe'nin nuget'te bulunan ClientCore kütüphanesini her iki projemiz referanslarına da ekleyelim ve bu kütüphaneyi kullanarak api'i eureka'a register edelim.

 

Startup.cs içerisinde bulunan ConfigureServices metodu içerisinde  services.AddDiscoveryClient(Configuration); diyerek uygulama servislerine ekleyip sonrasında Configure metodu içerisinde app.UseDiscoveryClient(); kodunu ekleyerek uygulamamızda eureka client'ı olarak tanımlamış olduk.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDiscoveryClient(Configuration);
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseDiscoveryClient();
    }
}

Ve son olarak kütüphane appsettings.json dosyasından okuduğu bazı conf. değerlerinide aşağıdaki gibi ekleyelim.

"spring" : {
    "application" : {
      "name" : "WeatherApi"
    }
  },
  "eureka" : {
    "client" : {
      "shouldRegisterWithEureka" : true,
      "serviceUrl" : "http://localhost:8761/eureka",
      "ValidateCertificates":  false
    },
    "instance" : {
      "appName" : "WeatherApi",
      "hostName" : "localhost",
      "port" : "55034",
      "healthCheckUrl": "/healthcheck"
    }
  }

Bu key'lerin ne anlama geldiğine bakacak olursak;

  • application.name: service'in ismi,
  • client.shouldRegisterWithEureka: service'in eureka'ya register olup olmaması gerektiğini belirten key. Eğer service'in diğer client'lar tarafından call edilmesini istiyorsak true set etmemiz gerekmekte,
  • client.serviceUrl: Eureka service adresi,
  • instance.appName: Diğer microservice'lerin bu service'imizi hangi isimle sorgulayacağını set ettiğimiz key,
  • instance.hostName: uygulamamızın host ismi,
  • instance.port: uygulamamızın host edildiği port b ilgisi.
  • instance.healthcheck: api için call edilecek healthcheck adresi

İlgili kodları sorunsuz bir şekilde ekledikten sonra api projemizi run edip sonrasında tekrardan eureka sayfasına giderek weatherApi'nin register olduğunu göreceksinizdir.

 

Calling Api Using Eureka

Artık api uygulamamız eureka'ya register oldu ve consoleApp içerisinden registery'e query atarak weatherApi'ı call etmeye hazırız. Bunun için ilk olarak consoleApp'de appsettings dosyasına aşağıdaki gibi yine eureka conf değerlerini ekleyelim ve uygulamamız service'lerine de eurekaClient'ı ekleyelim.

  "eureka": {
    "client": {
      "shouldRegisterWithEureka": false,
      "serviceUrl": "http://localhost:8761/eureka",
      "ValidateCertificates": false
    },
    "instance": {
      "appName": "WeatherConsoleApp"
    }
  },
  "WeatherApiUrl": "http://WeatherApi/"
serviceCollection.AddDiscoveryClient(_configuration);

Yukarıda görüldüğü üzre, weatherApiUrl olarak herhangi bir ipAddress yada port bilgisi vs tanımlamadık sadece eureka'da bulunan service ismini yazdık.Son olarak consoleApp api'ı call edeceğimiz yerde aşağıdaki gibi httpClient tanımını yaparak api'dan dönen response'u console'a yazdıralım.

    var handler = new DiscoveryHttpClientHandler(discoveryClient);
    var address = configuration.GetValue<string>("WeatherApiUrl")+"weather";
    using (var httpResponseMessage = new HttpClient(handler, false).GetAsync(address).Result)
    {
        var result = httpResponseMessage.Content.ReadAsStringAsync().Result;
        Console.WriteLine(result);
    }

 

Özetleyecek olursak; service discovery microservice geliştiren ekipler için oldukça önemli bir konudur. Sürekli olarak microservice'ler arası bir iletişim olduğundan ve uygulamalarınızı farklı deployment ortamlar olsun farklı data-center'lar olsun sürekli olarak dynamic-ip-assing söz konusu olabilmekte ve bu gibi sorunlara çözüm olarak Netflix Eureka ve sadece bunlardan bir tanesiydi. Steeltoe'nin sağlamış olduğu installation dosyalarını ve nuget paketlerini kullanarak bir kaç dkka içerisinde eureka-server ayağa kaldırıp uygulamalarını geliştirebilmenz mümkün hale gelebilmekte ancak yazımızın başındada dediğimiz gibi Kubernetes, nginx, Consul veya istio ile alternatif uygulamalarıda deneyebilirsiniz.

Source

Add comment