Web Sunucusunun Aldığı İstekleri Ne Kadar Sürede İşlediğini Kafka ve Go ile Kaydetme

ASP.NET WebAPI projesi

Web API’mızın iki tane end-point route’u olacak;

  • /api/products
    GET, POST, PUT, DELETE metotları ile istekler alabilecek ve dummy data oluşturmak için kullanılacak. Geri dönüşleri sadece 204 olacak ve içerisinde logic bir işlem yapılmayacak fakat bu metotlara giden istekler, 0 ile 3000 ms arası bekletilecek.
  • /health/api/products
    Son bir saatte /api/products’a giden isteklerin ne kadar sürede işlendiğinin bilgisini database’den alıp, sunacak.

ASP.NET WebAPI projesinin oluşturulması

dotnet new webapi -o server -n Kafka.Example

İhtiyacımız olan paketlerin eklenmesi

cd server
dotnet add package Confluent.Kafka
dotnet add package Npgsql

  • Npgsql
    Postgres database için kullanacağımız kütüphane.
  • Confluent.Kafka
    Kafka serverımız ile iletişim kurarken, Produce işlemleri için kullanacağımız kütüphane.

ResponseLog.cs

Database’den response sonuçlarını almak istediğimiz zaman kullandığımız model

Models/ResponseLog.cs

Services

  • FileLogService
    Gelen mesajı bir dosyaya kaydetmek ve kaydettiği bilgiyi, konsolda bildirmek.
  • KafkaLogService
    Gelen mesajı belirlenen bir topic’e göndermek(Produce etmek) ve gönderdiği bilgiyi konsolda bildirmek.

LogService.cs

Services/Abstract dizininin altına, LogService adında bir abstract class oluşturalım.

Services/Abstract/LogService.cs

FileLogService.cs

Services dizinin altına, FileLogService adında LogService’den kalıtım alan bir sınıf oluşturalım.

Services/FileLogService.cs

KafkaLogService.cs

Services/KafkaLogService.cs

ActionFilters

  • Delayer
    Delayer attribute’unu alan end-pointler’in rastgele bir değer aralığında bekletilmesini sağlamak için var.
  • TimeTracker
    Yaptığı tek bir iş var, oda TimeTracker attribute’unu alan bir yere istek giderse, isteğin end-point’e ilk ulaştığı süreyi HttpContext.Items dictionarysi içinde tutmak.

Delayer.cs

Filters/Delayer.cs

TimeTracker.cs

Filters/TimeTracker.cs

Routes

Yukarıda bahsettiğim gibi iki farklı routeumuz olacak ve bunların biri dummy data oluşturmak için kullanılacak. Diğeriyse bu dummy datayı sunmak için kullanılacak.

Products

Controllers altına, Products adında bir Controller oluşturalım.

Controllers/ProductsController.cs

Health

Controllers altına, Health adında bir Controller oluşturalım.

Controllers/HealthController.cs

Startup.cs

Yazdığımız servisleri DI ile eklemek, CORS’u belirtmek, kendi yazdığımız bir Middleware’ı kullanmak ve Dashboard ile kullanacağımız static ve default dosyaları kullanmasını belirtmemiz için Starup.cs dosyasına bi’ uğramamız gerekiyor.

ResponseLoggerMiddleware

Go ile Kafka mesajlarını okumak ve Database’ın güncellenmesi

ASP.NET WebAPI tarafından gönderdiğimiz Kafka mesajlarının consume edilmesi(okunması) ve database’e yazılmasına ihtiyacımız var. Bunun için ise basit bir programı Go ile yazdım.

initDatabase

insertMessages

consumeAndInsertMessages

main

Dashboard

Aslında Dashboard ile ilgili aktarabileceğim pek bir şey yok. Çünkü JavaScript hakim olduğum bir dil değil. Yaptıklarımı anlatabilirim ama yaptıklarımı olması gerektiği yollarla yaptığımı düşünmediğim için, Dashboard tarafındaki JavaScript kodlarından bahsedip, herhangi birini yanlış yönlendirmek istemiyorum. Fakat siz yine de inceleyebilirsiniz: Dashboard.

En sonunda elde ettiğimiz

  • Yapmak istediğimiz işlem için ilişkisel bir veritabanını kullanmak gereksiz, NoSQL bir database tercih edilmesi daha iyi olurdu.
  • Topic bir sabit olarak tutuluyor, ResponseLog ile hangi topic için işlem yapılacağı belirtilebilir.
    ResponseLog ile gelecek topic bilgisi ile hangi end-point route’undan geldiği bilgisi belirtilebilir ve ona ait bir dosyaya veya ona ait bir kafka topic’ine bu response log aktarılır.
    Örnek; şuanda sadece tek bir route’u izliyoruz ve bu route(/api/products). Herhangi yeni bir route’u izlemek istediğimiz zaman, bunun loglarını aynı topicte ve aynı dosyada tutmamız gerekecek, bunu yapabiliriz ama artık verilerimiz anlamlı bir veri olmaktan çıkar.
  • Aynı topicte tutarak, anlamlı/ayırt edici verileri nasıl elde edebiliriz?
    Farklı routelardan gelen ResponseLog’u aynı topicte tutarak ayırt edici hale getirebiliriz. Bunun için, ResponseLog’a yeni bir property ekleriz ve bu property, route bilgisini tutar ve artık ResponseLog mesajını şu hale getirebiliriz;
    /API/PRODUCTS GET 156 1628171244941
    /API/USERS PUT 50 1628171244941
    Bu değişiklikler sonrası, database tablomuza route’un ayırt edilmesi için bir alan daha eklemeliyiz ve Go ile yazdığımız consumer ve database güncelliyici buna göre şekillenmelidir. Aynı zamanda Health controller’ı ile sunulan verilerinde dışarıdan bir parametre ile filtrelenebilir olması gereklidir.
  • Dosyaya yazma işleminin Web Server tarafından yapılması yerine, consumer tarafından hem database’e insert etme hem de dosyaya yazma işlemi yapılabilirdi.
  • Dashboard’a veri sunuşunun optimize edilmesi gerekiyor, server tarafından sadece son bir saatte olan requestleri filtreleyip sunuyoruz ve Dashboard tarafında ise her seferinde son bir saatlik verileri gruplayıp onları chart’a veriyoruz. Çok fazla istek alan bir server için pek efektif bir yol değil.
    Eğer Dashboard ilk defa veri alıyorsa son bir saatlik verileri alarak, sonraki istekler içinse en son isteğin yapıldığı süreden sonraki kayıtların getirilmesi istenerek chart sadece yeni gelen verilerle birlikte güncellenerek, bu sorun çözülebilir.

--

--

https://halilkocaoz.com

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store