Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Distributed Application Runtime(Dapr) Nedir? Teorik ve Pratikte İnceleyelim

Merhaba,

Bu içeriğimizde microservice uygulamaları geliştirirken cloud’da resilient ve portable bir şekilde çeşitli dillerde çalışma olanağı sağlayan event-driven runtime olan Dapr(Distributed Application Runtime)’ın ne olduğu, microservice uygulamaları geliştirme süreçlerindeki yaşanılan zorlukların üstesinden gelinmesi için ne gibi yardımlarda bulunduğu ve nasıl kullanılabileceği hakkında uzun ve detaylı bir irdelemede bulunuyor olacağız.

Dapr(Distributed Application Runtime) Nedir?

Dapr, microservice uygulamaları oluşturmaya yönelik bir çok bileşenden oluşan bir araç kütüphanesidir. Dapr’ı kullanarak, mevcut uygulamalarınızı aşamalı olarak microservice mimarisine geçirebilir yahut sıfırdan başlayacağınız microservice projelerinizde Redis, RabbitMQ vs. gibi bağımlılıklara karşı oluşturulmuş encapsulation sayesinde oldukça esnek, genişletilebilir ve bağımsız bir geliştirme süreci benimseyebilirsiniz.

Tüm bunların yanında Dapr’ın platformdan bağımsız olması herhangi bir Kubernetes cluster’ında yahut sanal veya fiziksel makinelerde ya da Dapr’ın entegre olabileceği diğer barınma ortamlarında(hosting environments) çalıştırılabilmesini sağlamaktadır.

Dapr, Go dili kullanılarak Microsoft tarafından geliştirilmektedir ve ilk olarak 2019 yılında duyurulmuştur.

Dapr’la Hedeflenenler Nelerdir?

Dapr, modern dağıtılmış uygulamaların doğasında bulunan büyük bir zorluğu ele alıyor. Karmaşıklık… Pluggable Components mimarisi sayesinde dağıtılmış uygulamalardaki bağımlılıkların koordinasyonunu büyük ölçüde basitleştirerek çalışma imkanı sağlamaktadır.

Misal olarak; bir servisin stateful olmasını hedefleseydiniz muhtemelen Redis Cache gibi state’i store edebileceğiniz özel bir çalışma gerçekleştirirdiniz. Dapr ise direkt kullanıma hazır durum yönetimi sağlayabilecek bir yeteneğe sahiptir. Ve tabi arkaplanda Redis dahil olmak üzere farklı state store edilebilir componentleri de desteklemektedir.

Microservice Building Blocks

Dapr ile microservice geliştirme süreçlerinde istifade edebileceğimiz yapıtaşları aşağıdaki gibidir.Dapr İle Microservice Uygulama GeliştirmeGörüldüğü üzere Dapr, microservice uygulamaları geliştirirken, standart bir şekilde kullanılabilecek ve herhangi bir ortama deploy edilebilecek yetenekler sağlamaktadır. Dapr, geliştiricilerin uygulama sürecinde sadece Dapr building block’ları üzerinden işlem yapmasını sağlayacak ve böylece herhangi bir external library’e ihtiyaç duyurmayacağı için bağımlılıklar söz konusu olmayacaktır.

Dapr İle Microservice Uygulama GeliştirmeBuilding Block kavramını biraz daha açmamız gerekirse eğer yandaki görüntüyü inceleyebilirsiniz. Dikkat ederseniz bir building block içerisinde bir veya birden fazla component barındıran bir HTTP ya da gRPC API’ıdır. Bizler building block’lar sayesinde microservice uygulamalar oluştururken yaşanabilecek olan yaygın zorlukları esnek ve best practice’lere uygun bir şekilde ele alarak işleyebilmekteyiz.

Dapr, yeni building block’lar eklenerek genişletilebilir bir yapıya sahiptir.

Building block’ları, uygulamalar tarafından kullanılan modüler işlevsellikler olarak değerlendirebiliriz. Her bir işlevselliği ise bir component olarak değerlendirmekteyiz.

Dapr Components

Dapr, her işlevselliğin bir bilişen olarak sunulduğu modüler bir tasarım kullanmaktadır.
Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelimYukarıdaki görseli incelerseniz eğer Dapr’ın pluggable yapısı sayesinde her bir component’i işlevine göre farklı bir component’le rahatlıkla değiştirebilmekteyiz. Misal olarak; ‘State Stores’ operasyonu için default olarak ‘Redis’ component’i kullanılırken sizler isterseniz ‘Azure CosmosDB’ yahut ‘Cassandra’yı tercih ederek, rahatlıkla ve hiç zahmet etmeksizin geçiş sağlayabilir ve operasyonlarınıza yeni component’ten devam edebilirsiniz. Dapr, uygulamaları ve dolayısıyla geliştiricileri buradaki component’lerin konfigürasyonlarından soyutlayarak büyük ölçüde esneklik sağlamaktadır.

Component’lerin Özellikleri
Her bileşenin aşağıdaki formatta bir şartnamesi(specification) vardır.

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: [COMPONENT-NAME]
  namespace: [COMPONENT-NAMESPACE]
spec:
  type: [COMPONENT-TYPE]
  version: v1
  initTimeout: [TIMEOUT-DURATION]
  ignoreErrors: [BOOLEAN]
  metadata:
  - name: [METADATA-NAME]
    value: [METADATA-VALUE]

Bu şartnamedeki alanlar aşağıdaki işlevselliklere sahiptirler:

  • apiVersion, Dapr sürümünü ifade eder.
  • kind, CRD türünü ifade eder. (Component’ler için her daim tanımlanmalıdır)
  • metadata, Component hakkında bilgileri ifade eder.
  • name, Component’in adını ifade eder.
  • namespace, Component’lerin namespace’ini ifade eder.
  • spec, Component hakkında ayrıntılı bilgileri ifade eder.
  • type, Component’in türünü ifade eder.
  • version, Component’in sürümünü ifade eder.
  • initTimeout, Component’in başlatılması için zaman aşımı süresini ifade eder. Varsayılan olarak 5 saniyedir.
  • ignoreErrors, Component yüklenemezse hataları görmezden gelerek Dapr’ın çalışmasını devam ettirir. Varsayılan olarak false değerindedir.
  • metadata, Component’e özel key/value çift yapılandırma değerlerini ifade eder.

Built-in Components
Dapr, yukarıdaki görselde de anlaşılacağı üzere community’ler tarafından geliştirilip hizmetimize sunulan dahili component’lere sahiptir. Bunların dışında Dapr, kendimize özel olarak(custom) component’ler de geliştirip kullanmamıza olanak tanımaktadır.

Şimdi dahili olan ve hazır bulunan, kullanılabilir component türlerini inceleyerek genel anlamda fikir edinmeye çalışalım.

Component Types Detail
State stores Veri depolarıdır.Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelim
Name resolution Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelim
Pub/sub brokers Pub/sub işlemlerini yürüten message broker’lardır.Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelim
Bindings Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelim
Secret stores Gizli bilgileri depolamak için kullanılır.Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelim
Configuration stores Uygulama konfigürasyonel verilerini depolamak için kullanılırlar. Değişiklik meydana geldiğinde bildirimde bulunurlar.Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelim
Locks Distributed lock.
Middleware Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelim

Dapr Yapılandırma

Dapr bir YAML dosyası üzerinden kolayca yapılandırılabilmektedir. Misal olarak aşağıda Dapr’ın metrik bilgilerinin nereye gönderileceğine ilişkin bir endpoint konfigürasyonu örneklendirilmektedir.

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: daprConfig
  namespace: default
spec:
  tracing:
    samplingRate: "1"
    zipkin:
      endpointAddress: "http://localhost:9411/api/v2/spans"

Ayrıca aşağıdaki ‘dapr-system’ namespace’inde ‘daprsystem’ olarak isimlendirilen Dapr konfigürasyon örneğini de inceleyebilirsiniz.

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: daprsystem
  namespace: dapr-system
spec:
  mtls:
    enabled: true
    workloadCertTTL: "24h"
    allowedClockSkew: "15m"

Dapr Observability/İzleme/Gözlenebilirlik

Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelimBir uygulamanın, en hayati noktalarından birisi çalışma zamanında nasıl davrandığını izleyebilmektir. Özellikle uygulama çağrılarının gözlenebilmesi, performans durumunun ölçümlenebilmesi yahut meydana gelen beklenmeyen problemlerin anında çözülebilmesi, hataların ayıklanabilmesi veya oluşacak darboğazların(bottlenecks) anlaşılabilmesi için gözlenebilirlik oldukça önem arz etmektedir. Evet, biliyorsunuz ki bu herhangi bir sistem için zordur lakin bir istek neticesinde küçük mikro servisler arasında akış silsilesinin söz konusu olduğu distributed bir sistem için daha da zordur.

Bir uygulamayla ilgili bellek tüketimi, CPU kullanımı vs. gibi temel seviyedeki metrikler rahatlıkla alınabiliyor olsa da asıl önemli olan bir çağrı sürecinde uygulamanın davranışına dair anlamlı bilgilerin toplanmasıdır. Ve bu da geliştirici açısından ihtiyaç noktalarına kodsal müdahalelerde bulunulması gerektiği anlamına gelmektedir. Çoğu zaman toplanan bu metrikler türlü araçlarla görselleştirilerek monitör edilirler.

Şimdi mantıken olaya baktığımızda uygulamaların business logic’inin bir parçası olmayan bu çalışmaları gerçekleştirmek geliştiriciler açısından ciddi bir yüktür ve hatta bu yük bu araçların SDK’lerini kullanma, API’lerini anlama vs. gibi durumları gerektirdikçe daha da ciddi hale gelebilmektedir.

Bir çağrım sonucu mikro servisler arasında akışın başladığı durumlarda Dapr bu distributed senaryolarda gözlenebilirlik açısından avantaj sağlamakta ve yaygın olarak kabul gören Open Telemetry (OTEL) veya Zipkin protokolleri ile metrikleri toplayabildiği için birçok görselleştirme aracıyla kolayca entegre edilebilmektedir.

Ayrıca Dapr, kullanıcıların sorunlarını tanımlamasına ve hata ayıklama yapmasına yardımcı olmak için içerisinde uyarı, hata ve bilgi mesajları barındıran log‘larla birlikte, sistemin durumunu kontrol edebilmek için bir Health Check mekanizması da barındırmaktadır.

Dapr Nasıl Yüklenir?

Dapr’ı kullanabilmek için öncelikle Dapr CLI’ı bilgisayarınıza kurmanız gerekmektedir. Bunun için şu adresteki önergeleri sırasıyla takip etmeniz yeterlidir.

Powershell üzerinden Dapr’ı yükleyiniz.
Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelimArdından dapr komutuyla yüklenip, yüklenmediğini doğrulayınız.Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelimSelf-hosted modda Dapr’ı çalıştırınız.Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelimVe Dapr container’larını listeleyip nihai kontrolde bulununuz.Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelimGörüldüğü üzere Dapr temel olarak ‘Redis’, ‘Openzipkin/Zipkin’ ve ‘Daprio/Dapr’ olmak üzere üç container ile başlangıç sağlamaktadır. ‘Openzipkin/Zipkin’ container’ı ile metrikleri toplarken, ‘Redis’ ile state-store ve messaging operasyonlarını yürütmektedir. Ayrıca bu component’lerin Windows işletim sistemlerinde C:\Users\[name]\.dapr klasörü altında tanımlandıklarını bilmenizde fayda vardır. (Linux’da ise $HOME/.dapr dizininde tanımlanmaktadır)

Dapr İle Basit Düzeyde Servislerin Haberleşmesi

Şimdi ise son olarak Dapr ile basit seviyede iki servisin haberleşmesini inceleyerek içeriğimizi nihayete erdirelim istiyorum. Bunun için boş bir solution’da ‘Dapr.Basic.ServiceA’ ve ‘Dapr.Basic.ServiceB’ isimlerinde olmak üzere iki Asp.NET Core API uygulamasını aşağıdaki gibi oluşturunuz.
Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelim
Şimdi bu servisler arasında publish edilmiş event üzerinden haberleşmeyi sağlayabilmek için herhangi bir kütüphane, teknoloji vs. düşünmeksizin direkt olarak Dapr ile bu işlemi gerçekleştirebileceğiz.

Burada ‘Dapr.Basic.ServiceA’ servisi ile event publish edilirken ‘Dapr.Basic.ServiceB’ servisi ile de bu event’i dinleyecek ve gerekli işlemleri gerçekleştireceğiz.

Tabi bu işlemi SDK kullanarak yahut HTTP üzerinden istekte bulunarak iki farklı şekilde gerçekleştirebiliriz. Şimdi gelin her iki yöntemle de nasıl çalışma sağlayabiliriz sırasıyla inceleyelim;

  • SDK
    SDK üzerinden geliştirmeyi sağlayabilmek için event publish edecek olan ‘Dapr.Basic.ServiceA’ isimli servise Dapr.Client ve Dapr.AspNetCore library’lerini, tüketici olan ‘Dapr.Basic.ServiceB’ isimli servise ise sadece Dapr.AspNetCore library’sini yükleyiniz.

    Ardından ‘Dapr.Basic.ServiceA’da aşağıdaki çalışmayı gerçekleştiriniz.

    using Dapr.Client;
    using Shared.Events;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddControllers();
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddDaprClient();
    
    var app = builder.Build();
    
    app.MapGet("/send-event/{eventText}", async (string eventText, DaprClient client) =>
    {
        await client.PublishEventAsync(pubsubName: "pubsub", topicName: "example.event", new Event(eventText));
        Console.WriteLine(eventText);
    });
    
    app.UseHttpsRedirection();
    app.MapControllers();
    app.Run("https://localhost:1000");
    

    Yukarıdaki kod bloğunda, 8. satırda ‘AddDaprClient’ servisi uygulamaya dahil edilmekte ve 12 ile 16. satır aralığında ise /send-event/{eventText} endpoint’i içerisinde ‘Event’ türünden bir event publish edilmektedir. Burada ‘pubsubName’e C:\Users\[name]\.dapr dizininde bulunan ‘components’ klasörü içerisindeki ‘pubsub.yaml’ dosyasının ‘metadata:name’ bilgisinin verildiğine dikkatinizi çekerim.Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelim‘Dapr.Basic.ServiceB’ servisinde ise aşağıdaki çalışmayı gerçekleştiriniz.

    using Dapr;
    using Shared.Events;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddControllers().AddDapr();
    builder.Services.AddEndpointsApiExplorer();
    
    var app = builder.Build();
    
    app.MapPost("/get-event", [Topic("pubsub", "example.event")] (Event @event) =>
    {
        Console.WriteLine(@event.Text);
    });
    
    app.UseHttpsRedirection();
    app.UseCloudEvents();
    app.MapControllers();
    app.MapSubscribeHandler();
    app.Run("https://localhost:2000");
    

    Burada da 6. satırda Dapr ‘AddDapr’ extension’ı sayesinde MVC pipeline’ına dahil edilmektedir. 17. ve 19. satırlarda ise sırasıyla ‘UseCloudEvents’ ve ‘MapSubscribeHandler’ middleware’leri çağrılmaktadır. Dapr, publish edilen event’ları CloudEvent formatına çevirdiği için aynı şekilde event’i ilgili türe dönüştürebilmek amacıyla ‘UseCloudEvents’ middleware’i kullanılmaktadır. ‘MapSubscribeHandler’ middleware’i ise 11. satırda yayınlanmış olan event’i dinleyebilmek için kullandığımız Topic attribute’unu işlevsel hale getirebilmek için çağrılmaktadır.

    Bu işlemlerden sonra aşağıdaki talimatlar eşliğinde Dapr üzerinden servisleri ayağa kaldırınız ve ekran görüntüsündeki gibi teste tabi tutunuz.
    dapr run --app-id servicea --app-ssl --app-port 1000 -- dotnet run
    dapr run --app-id serviceb --app-ssl --app-port 2000 -- dotnet run
    (SSL connection kullanan uygulamalarda –app-ssl parametresi ile Dapr’a güvenli olmayan bir SSL bağlantısı üzerinden uygulamaları ayağa kaldırması gerektiğini söylemiş oluyoruz.)
    Distributed Application Runtime(Dapr) Nedir Teorik Olarak İnceleyelimGörüldüğü üzere Dapr sayesinde publish ettiğimiz event herhangi bir harici kütüphaneye ihtiyaç duymaksızın direkt subscribe olan bir consumer tarafından başarıyla işlenmektedir.

  • HTTP
    Benzer şekilde iki servis arasındaki haberleşmeyi HTTP üzerinden sağlamak istiyorsanız burada birazcık farklı davranış sergilemeniz gerekmektedir.

    ‘Dapr.Basic.ServiceA’ servisinde aşağıdaki gibi bir çalışma gerçekleştiriniz;

    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddControllers();
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddDaprClient();
    
    var app = builder.Build();
    
    app.MapGet("/send-event/{eventText}", async (string eventText, DaprClient client) =>
    {
        HttpClient httpClient = new();
    
        Event @event = new(eventText);
        string jsonData = JsonSerializer.Serialize(@event, options: new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
    
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json));
        StringContent body = new(jsonData, Encoding.UTF8, MediaTypeNames.Application.Json);
        var response = await httpClient.PostAsync($"http://localhost:2001/v1.0/publish/pubsub/example.event", body);
    
        return Results.Ok($"Status Code : {response.StatusCode} | Event : {@event.Text}\"");
    });
    
    app.UseHttpsRedirection();
    app.MapControllers();
    app.Run("https://localhost:1000");
    

    Yukarıdaki kod bloğunu incelerseniz eğer 11 ile 20. satır aralığında HTTP protokolü üzerinden bir event yayınlama işlemi gerçekleştirilmektedir. Bu işlem için 18. satırda http://localhost:2001/v1.0/publish/pubsub/example.event adresine POST isteği gönderilmektedir. Bu adreste nerden çıktı hoca la? diye sorduğunuzu duyar gibiyim… Tabi ki de kafamıza göre bir adres yazıp istekte bulunmadığımız aşikar. Dapr, HTTP üzerinden gerçekleştirilecek pub/sub işlemleri için aşağıdaki formatta bir url’e istek göndermemiz gerektiğini bizlere söylemektedir.
    http://localhost:<daprPort>/v1.0/publish/<pubsubname>/<topic>[?<metadata>]
    Bu adres şemasındaki <daprPort>, haberleşme sağlanmak istenen servisin birazdan nasıl tanımlanabileceğini göreceğimiz Dapr HTTP Port’una karşılık gelmektedir. <pubsubname>, hangi pub/sub component’i kullanılıyorsa onun adına karşılık gelmektedir. Ve son olarak <topic> ise event’in publish edildiği topic adına karşılık gelmektedir.

    HTTP protokolü üzerinden çalışma sürecinde, yukarıdaki gibi bir event publish edildiği taktirde; Dapr, consumer görevi gören serviste
    http://localhost:<appPort>/dapr/subscribe endpoint’ini GET request’i ile tetiklemektedir. Böylece ilgili serviste bir event’in publish edildiğine dair bilgilenilmiş olunacaktır. Şimdi bu mantık doğrultusunda ‘Dapr.Basic.ServiceB’ servisini ise aşağıdaki gibi geliştiriniz.

    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    
    app.MapGet("/dapr/subscribe", () =>
    {
        return Results.Json(new[] {new
        {
            PubSubName = "pubsub",
            Topic = "example.event",
            Route = "/get-event"
        } });
    });
    
    app.MapPost("/get-event", (DaprData<Event> @event) =>
    {
        Console.WriteLine(@event.Data.Text);
    });
    
    app.Run("https://localhost:2000");
    record DaprData<T>(T Data);
    

    Yukarıdaki çalışmaya dikkat ederseniz, 4 ile 12. satır aralığında herhangi bir event yayınlandığı taktirde Dapr tarafından tetiklenecek olan /dapr/subscribe endpoint’ine karşılık bir minimal api tanımlanmıştır. Bu action içerisinde, JSON olarak ‘PubSubName’, ‘Topic’ ve ‘Route’ bilgilerini barındıran bir obje, üretilmiş bir koleksiyona dahil olacak şekilde geriye return edilmektedir. Burada ‘Route’ta tanımlı olan /get-event değeri sayesinde publish edilmiş olan event’ın hangi endpoint içerisinde handle edileceği ifade edilmektedir. Dolayısıyla bu aşamadan sonra 14 ile 17. satır aralığındaki action tetiklenecektir.

    İlgili action’a göz atarsanız eğer 20. satırda tanımlanmış olan ‘DaprData<T>’ record türünden bir parametre almaktadır. Burada T yerine ‘Event’ yazılarak gelen değer tam olarak elde edilmiş olmaktadır. Bu tarz bir çalışmanın nedenini sorarsanız eğer bu metota gelen verinin yapısının aşağıdaki gibi olmasıdır.

    {
      "data": {
        "text": "nevin"
      },
      "datacontenttype": "application/json; charset=utf-8",
      "id": "dfd6a336-b99f-4cc7-a384-b8a31ca4f791",
      "pubsubname": "pubsub",
      "source": "serviceb",
      "specversion": "1.0",
      "time": "2022-11-14T01:26:03+03:00",
      "topic": "example.event",
      "traceid": "00-97ecee8642fbcf8549f43db6f9d7074c-4b255f63bafe0b31-01",
      "traceparent": "00-97ecee8642fbcf8549f43db6f9d7074c-4b255f63bafe0b31-01",
      "tracestate": "",
      "type": "com.dapr.event.sent"
    }
    

    Görüldüğü üzere birçok bilgi tek bir json datası içerisinde kümülatif olarak gelmektedir. Haliyle burada publish edilmiş event’i temsil edebilmek için bu json datasının içerisindeki ‘data’ parametresini alabilecek bir çalışma yapmamız gerekecekti. Bunun için generic bir record ile gayet efektif bir çözüm getirebildik kanaatindeyim 🙂 Action tetiklendiğinde deserialize süreci başlatılacak ve ‘DaprData<T>’ türüne göre bir çıktı alınacaktır. Ee ‘DaprData<T>’ türü de içerisinde ‘Data’ parametresi aldığı için ilgili json içerisindeki ‘data’ bu parametreyle eşleşecek ve bizlere direkt T parametresine verilen türde değeri getirecektir.

    İşte bu kadar…

    Son olarak aşağıdaki talimatlar eşliğinde uygulamaları Dapr üzerinden ayağa kaldırıp, testlerinizi gerçekleştiriniz.
    dapr run --app-id servicea --app-ssl --app-port 1000 --dapr-http-port 1001 -- dotnet run
    dapr run --app-id serviceb --app-ssl --app-port 2000 --dapr-http-port 2001 -- dotnet run
    (–dapr-http-port … parametresi ayağa kaldırılan uygulamanın Dapr’da HTTP üzerinden erişilebilen port’unu ifade etmektedir. Yukarılarda bahsi geçen <daprPort> alanına ilgili servisin –dapr-http-port bilgisi verilmelidir.)
    Distributed Application Runtime(Dapr) Nedir? Teorik ve Pratikte İnceleyelimEvet, böylece yine herhangi bir kütüphane kullanmaksızın Dapr ile HTTP üzerinden iki servisin haberleşmesini sağlayabilmiş bulunuyoruz.

Component Değiştirme

Dapr’ın component’leri barındırdığı default path’inin Windows için C:\Users\[name]\.dapr, Linux için ise $HOME/.dapr olduğunu daha önceki satırlarımızda bildirmiştik.

Bir component’i değiştirmek istediğimizde tek yapılması gereken ilgili YAML dosyasının istenilen component içeriği ile değiştirilmesidir. Misal olarak, içeriğimiz sürecinde default olarak gelen ve pub/sub componenti olarak kullanmış olduğumuz Redis’i RabbitMQ component’i ile değiştirmek istiyorsak eğer yapmamız gereken şuradan RabbitMQ component’ine ait formatı alıp ilgili dizindeki ‘pubsub.yaml’ dosyası içerisindekilerle değiştirmektir.

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: rabbitmq-pubsub
spec:
  type: pubsub.rabbitmq
  version: v1
  metadata:
  - name: host
    value: "amqps://xfj***.rmq.cloudamqp.co**hzhsq"
  - name: consumerID
    value: myapp
  - name: durable
    value: false
  - name: deletedWhenUnused
    value: false
  - name: autoAck
    value: false
  - name: deliveryMode
    value: 0
  - name: requeueInFailure
    value: false
  - name: prefetchCount
    value: 0
  - name: reconnectWait
    value: 0
  - name: concurrencyMode
    value: parallel
  - name: publisherConfirm
    value: false
  - name: backOffPolicy
    value: exponential
  - name: backOffInitialInterval
    value: 100
  - name: backOffMaxRetries
    value: 16
  - name: enableDeadLetter # Optional enable dead Letter or not
    value: true
  - name: maxLen # Optional max message count in a queue
    value: 3000
  - name: maxLenBytes # Optional maximum length in bytes of a queue.
    value: 10485760
  - name: exchangeKind
    value: fanout

Tabi burada RabbitMQ sunucusu cloud yahut docker ortamlarından hangisindeyse ona göre host yolunun ve diğer konfigürasyonların yapınıza göre özelleştirilmesi gerekmektedir.

Velhasıl kelam, component değişikliğini yaptıktan sonra Dapr’ı kaldırıp Self-hosted modda tekrardan ayağa kaldırmanız gerekmektedir.
Distributed Application Runtime(Dapr) Nedir? Teorik ve Pratikte İnceleyelim

Component Dizinini Değiştirme
Component dosyalarını(YAML) bulundukları default dizinin dışında istediğimiz herhangi bir path’e de taşıyabiliriz. Misal olarak solution ile aynı dizinde olan ‘Components’ isimli bir klasör içerisine koymak istediğimizi varsayarsak eğer bunun için Dapr ile uygulamaları ayağa kaldırırken aşağıdaki gibi talimat sürecinde –components-path parametresi ile değer olarak ilgili path’i geçmeliyiz.

dapr run --app-id servicea --app-ssl --app-port 1000 --dapr-http-port 1001 --components-path ../components -- dotnet run
dapr run --app-id serviceb --app-ssl --app-port 2000 --dapr-http-port 2001 --components-path ../components -- dotnet run

Dapr Dashboard

Dapr, yapılan tüm çalışmaları sağlamış olduğu dashboard üzerinden görselleştirerek bizlere sunmaktadır. Bunun için dapr dashboard talimatını vererek dashboard’u 8080 portunda ayağa kaldırabilir ve http://localhost:8080 adresi üzerinden direkt erişim gösterebilirsiniz.Distributed Application Runtime(Dapr) Nedir? Teorik ve Pratikte İnceleyelimDistributed Application Runtime(Dapr) Nedir? Teorik ve Pratikte İnceleyelim

Dapr Observability/Zipkin UI

Dapr, toplamış olduğu çeşitli metrikleri farklı UI teknolojilerini de destekleyecek şekilde default olarak Zipkin ile görselleştirmektedir. Zipkin UI’ı açabilmek için direkt localhost:9411 adresine tarayıcıda istek göndermeniz yeterlidir.Distributed Application Runtime(Dapr) Nedir? Teorik ve Pratikte İnceleyelimEkran görüntüsünden de anlaşılacağı üzere servisler arası pub/sub temelli haberleşmelerden tutun, hemen hemen tüm bilgileri Dapr’ın observability özelliği sayesinde elde ederek, gözlemleyebilmekteyiz.

Dapr – Visual Studio Code Extension

Dapr, uygulamalarımızı daha iyi yönetmek ve debug edebilmemiz için Visual Studio Code üzerinden bir extension sunmaktadır.

İlgili extension’a aşağıdaki adresten erişim gösterebilirsiniz.
https://docs.dapr.io/developing-applications/ides/vscode/vscode-dapr-extension/

Bu extension ile Dapr’da ayağa kaldırılmış uygulamalara HTTP request’leri atabilir yahut event yayınlayarak testlerinizi gerçekleştirebilirsiniz.

Nihai olarak,
Görüldüğü üzere, çağın gereği olarak yazılımsal operasyonlarda her ne kadar sorumlulukları farklı servislere bölerek distributed yaklaşımlar sergiliyor olsakta ve bu sergilediğimiz yaklaşımlar neticesinde bütünsel olarak yazılımın performansı ve verimliliği için en efektif yolları bulabilmek maksadıyla türlü türlü çabalara ve teknolojilere başvuruyor olsakta dikkat ederseniz bu dağılmışlığın getirisi olan karmaşıklığı yönetebilmek için yine tek elden çözümlere yöneliyoruz. Evet, adına microservice diyoruz ama işin doğası gereği tüm bu parçalanmış yapıyı yönetebilmek için monolitik düşünceden hala vazgeçemiyoruz 🙂 Çünkü dediğim gibi işin doğasında bu var… Dağıtmak lakin tek bir standart ile dağıtmak var…

İşte bu standartlardan biri olan Dapr’ı mümkün mertebe teferruatlı incelemeye ve pratiksel olarak tecrübe etmeye çalışmış olduk…

Üşenmeden okuyup, eşlik ettiğiniz için teşekkür ederim…

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Not : Örnek çalışmayı aşağıdaki github adresinden edinebilirsiniz.
https://github.com/gncyyldz/Dapr_Examining

4 Cevaplar

  1. Ömer Turanoğlu dedi ki:

    Hocam merhaba

    dapr run --app-id servicea --app-ssl --app-port 1000 --dapr-http-port 1001 -- dotnet run
    dapr run --app-id serviceb --app-ssl --app-port 2000 --dapr-http-port 2001 -- dotnet run
    

    bu komutları çalıştırınca

    couldn’t find a project to run. ensure a project exists in C:Users\Asus\Desktop\Dapr, or pass the path to the project using – project.

    uyarısı alıyorum. ne yapabilirim?

  2. Can Cuma Yaman dedi ki:

    Hocam çok bilgilendirici bir yazı olmuş teşekkür ederim. Emeğinize sağlık.

  3. Murat dedi ki:

    Merhabalar,

    Dapr üzerinde birden fazla bileşeni yaml dosyada GLOBAL olarak nasıl belirtebiliriz?
    Ör:
    Redis, RabbitMQ ve NATS bileşenlerini PUBSUB olarak aynı anda nasıl tanımlarız?

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir