.NET Core’da Consul Kullanımı — Configuration Management

Engincan Veske
SDTR
Published in
4 min readOct 30, 2021
Consul

Herkese merhaba,

Bu yazımda .NET Core tarafında ayarlarımızı merkezi bir noktadan, UI üzerinden değiştirebilmemizi/yönetebilmemizi sağlayan Consul aracından bahsetmek istiyorum. İlk olarak Consul’un ne olduğundan ve kullanılmasının bizim açımızdan ne gibi avantajlar sağladığından bahsederek başlayalım.

Consul Nedir?

Consul’un ne olduğundan ve bizim için sağladığı avantaj/kolaylıklardan bahsetmeden önce, bir uygulamada; uygulama bazlı ayarlarımızı tutabileceğimiz kaynakları gözden geçirelim.

Uygulama bazlı ayarları saklayabileceğimiz/tutabileceğimiz yerler:

1-) Uygulama ayarlarında (appsettings.json, appsettings.development.json, environment variables vs.),

2-) Veri tabanında,

3-)Bir key-value store’da (Consul burada devreye giriyor)

  • appsettings.json gibi bir dosyada ilgili verilerimizi tutmak bizim için performans açısından herhangi bir dezavantaj sağlamayacaktır. Basit bir şekilde ilgili ayarları key-value şeklinde ilgili dosyada saklayarak, daha sonra ilgili ayarlar bazından işlemleri gerçekleştirebiliriz. Fakat böyle olması durumunda UI üzerinden basit bir şekilde bu ayarların yönetimini sağlayamayacağız. Ayrıca her geliştirici ilgili ayar değişikliğinde bunu commitlemek durumunda kalacak.
  • Veri tabanı açısından baktığımızda ise, her seferinde veri tabanından ilgili ayarı çekip ona göre bir işlem yapılacağı için bir performans kaybı söz konusu, elbette bu noktada cache mekanizması kullanılarak bu performans sorunu iyileştirilebilir fakat bir ayarın değiştirilmesi durumunda cache invalidation durumu devreye gireceği için harcadığımız eforun artacağını söyleyebiliriz.
  • Diğer bir yöntem olan ve ayarlarımızı bir key-value store da tutma seçeneğini düşünecek olursak, pub/sub pattern ile kullanarak uygulama runtime’ında ilgili değişiklikleri yükleyebiliriz ve bu sayede cache invalidation ile uğraşmamıza gerek kalmadan her değişiklikte dinamik olarak ilgili ayarlara ulaşabiliriz.

Burada önümüzdeki seçeneklerimizi değerlendirdiğimizde, ayarlarımızı key-value store da tutmanın işlerimizi kolaylaştırdığı ve merkezi bir ayar yönetimi sağlamamıza olanak sağladığını görebiliriz. İşte bu noktada key-value store seçeneklerinden Consul’u kullanabiliriz.

Consul bizim için bir distributed key-value store görevi görerek, uygulama ayarlarımızı merkezi bir noktada tutabileceğimiz ve uygulama içinde kolay bir şekilde kullanacağımız bir seçim olmuş oluyor.

.NET Core Tarafında Consul Kullanımı

Consul’un ne olduğundan ve bizim için ne gibi avantajlar sağladığından bahsettikten sonra artık basit bir .NET Core Web Api projesi oluşturabilir ve kullanımına geçebiliriz.

Uygulamanın kaynak koduna https://github.com/EngincanV/Asp.Net-Core-Consul-Demo adresinden ulaşabilirsiniz.

İlk olarak Docker üzerinde, Consul uygulamamızı çalıştıralım. Bunun için aşağıdaki komutu kullanabiliriz.

docker run -d -p 8500:8500 -p 8600:8600/udp --name=my-consul consul agent -server -ui -node=server-1 -bootstrap-expect=1 -client=0.0.0.0

Bu komutu çalıştırdıktan sonra, http://localhost:8500 adresine giderseniz aşağıdaki fotoğrafa benzer bir görüntü ile karşılaşmanız gerekiyor.

Consul UI

Docker üzerinden Consul uygulamamızı çalıştırdığımıza göre artık basit bir Web API projesi oluşturabiliriz. CLI üzerinden oluşturmak isterseniz aşağıdaki komut ile bir Web API projesi oluşturabilirsiniz.

dotnet new webapi --name Consul.Demo --output .

Uygulamamızı oluşturduktan sonra Consul paketini Nuget üzerinden uygulamamıza kurmamız gerekiyor. CLI üzerinden aşağıdaki komut ile ilgili paketi Web API projesine ekleyebilirsiniz.

dotnet add package Consul --version 1.6.10.3

İlgili paketi de ekledikten sonra artık Consul üzerinde tanımladığımız (bir sonraki adımda tanımlayacağız) ayarları uygulamamız içinde kullanabilmemiz için gerekli yapılandırmaları yapmamız gerekiyor.

İlk olarak Extensions adında bir klasör oluşturalım ve bu klasör içinde ServiceCollectionExtensions.cs adında bir sınıf oluşturarak aşağıdaki kodları ekleyelim.

ServiceCollectionExtensions.cs

Daha sonra ise Startup.cs veya Program.cs (projeyi .NET 6 ile oluşturduğum için Startup.cs sınıfı bulunmuyor ve bütün ayarlar bu sınıf üzerinden sağlanıyor, sizde .NET 6 projesi oluşturduysanız aşağıdaki kodları bu sınıfa ekleyebilirsiniz) dosyamızı açarak ilgili yapılandırmaları sağlayalım.

Program.cs

İlgili yapılandırmayı tamamladıktan sonra basit bir provider sınıfı oluşturarak, girdiğimiz key değerine göre bize istediğimiz tipte değer dönen bir method yazalım. Bunun için Helpers adında bir klasör oluşturarak içine ConsulKeyValueProvider adında bir sınıf ekleyelim ve aşağıdaki kodlar ile bu sınıfı dolduralım.

ConsulKeyValueProvider.cs
  • Burada ConsulClient sınıfı sayesinde, Consul ile (http://localhost:8500 adresinde çalışan) iletişim kurarak, girdiğimiz anahtar/key değerine göre istediğimiz değeri istediğimiz tipte değeri elde edebileceğimiz basit bir method oluşturduk.
  • http://localhost:8500 adresine giderek, Key/Value bölümünü seçelim ve oradan da bir key-value değeri oluşturarak bu methodumuzu test edelim.

Ben burada ConsulDemoKey adında bir key oluşturarak, yukarıdaki fotoğrafta olduğu gibi birkaç değer (IsEnabled, ShowMessage ve Message) atadım. Artık .NET Core uygulamamda, bir önceki adımda oluşturmuş olduğumuz yardımcı methoda key olarak ConsulDemoKey vererek bu değerlere ulaşabilmem gerekiyor. Bunu uygulamada test etmek için, Controllers klasörü altındaki WeatherForecastController sınıfını açalım ve Get methodunu aşağıdaki gibi güncelleyelim.

WeatherForecastController.cs
  • Buradaki kodu inceleyecek olursak, ConsulDemoKey adında bir sınıfın olduğunu görebiliriz. Consul üzerinde key-value cinsinden değer atarken, value yu json olarak tanımladığımız için bir sınıf oluşturarak ilgili değerlerin eşleşmesini (maplenmesini) sağlayabiliriz.
  • ConsulDemoKey sınıfını Models klasörünün altında aşağıdaki gibi tanımlayabiliriz.
ConsuleDemoKey.cs

Yapmak istediğimiz herşeyi tamamladığımıza göre artık uygulamayı çalıştırarak sonuca bakabiliriz.

Uygulamamızı çalıştırıp /WeatherForecast route’una istek yolladığımızda beklediğimiz gibi ilgili değerler Consul dan okunarak ekrana yazdırıldı.

Burada uygulamamızı kapatmadan, Consul üzerinden ilgili bir değeri değiştirir isek (Örneğin: Message’ı “Dynamic Configuration with Consul” olarak değiştirebiliriz), dinamik bir şekilde ilgili değişikliğin ekrana yansıdığını görebiliriz.

--

--