Azure Storage - Queue Nedir?

   

Azure Storage servisleri içerisinde Queue, Blob, Table, File(preview) gibi farklı depolama seçenekleri var, ben bu post'ta Queue'ya değineceğim.

Nedir bu Queue?

Queue, türkçede kuyruk.

Bilgisayar mühendisliği veya benzeri bölümler okuyan arkadaşların iyi hatırlayacağı üzere queue(kuyruk) bir abstract data type (ADT), aslında bakarsanız Azure üzerinde kuyruk kullanmak o derste öğretilen kadar zor ve karmaşık değil.

   

Yukarıdaki resim MSDN'den aldığım bir image ve bence kuyruğu en iyi ifade eden görsellerden biri.

Öncelikle bileşenleri tanıtıyım,

  • Solda görmüş olduğunuz Web Role -> bildiğiniz web sitesi
  • Orta ve aşağıdaki Windows Azure Queue -> türkçesi kuyruk, bu arkadaşın nasıl çalıştığını anlamaya çalışıyoruz.
  • Sağdaki Worker Role -> basit olarak anlatmak gerekirse sürekli çalışan bir program.

   

Yukarıdaki görselde gördüğünüz gibi kuyruğa sürekli web sitesi tarafından bir şeyler ekleniyor ve worker role bunları okuyup işliyor. Tam olarak üniversitelerde öğrenmiş olduğumuz kuyruk yapısı gibi "FIFO" first-in-first-out çalışmıyor aslına bakarsanız. Buna daha sonra değiniriz.

   

Örnek senaryo

Bir e ticaret sitemiz olduğunu düşünelim ve kullanıcı ödeme işlemenini yaptıktan sonra 3 farklı işlem yapılması gerektiğini düşünelim.

  • Satış stok takip programına işlenmeli
  • Kargo firmasının api'lari ile işlem yapılmalı
  • Kullanıcıya mail atılmalı

Bu işlemlerin hepsi kullanıcı ödemesini tamamladıktan sonra yapılmalı. Baktığımızda bu işi buton'a basıldığında yapabiliriz diye düşünebiliriz ancak gerçekte iş biraz daha karışık. Butona basıldığı anda bu kadar işi bir anda yaparsanız kullanıcı cok fazla bekler belkide request timeout olur. Bu işlemlerden bazıları o anda teknik sebeplerden ötürü yapılamaya bilir ve sizin bir retry logic kurmanız gerebilir. Bu konuların hepsinden kaçınıp kuyruk kullanarak bu senaryoyu başarabiliriz.

Nasıl yapmalıyız?

Kullanıcı ödeme işlemini tamamladığından bu satış işleminin identifier'ini web sitesi kuyruğa koyar. Worker role bu kuyruğu sürekli kontrol eder ve satış bilgisi geldiği anda yukarıdaki 3 adımı sırası ile gerçekleştirir. Eğer bir hata oluşursa otomatik olarak kuyruğa tekrar ekler ve ilerleyen zamanlarda tekrar dener.

   

Dizayn olarak bakacak olursak, bu yapıyı kullanarak sistemlerimizi birbirinden bağımsız hale getirirerek daha iyi bir mimari dizayn ortaya koyabiliriz. Örneğin bizim birden çok e ticaret sitemiz var ancak hepsi için az önce yukarıda anlattığımız senaryo aynı, bütün siteler tek depo ile çalışıyor ve aynı kargo firması ile çalışıyor. Bu durumda farklı web sitelerimiz aynı kuyruğa mesaj koyabilir ancak okuyacak worker role bunların nereden geldiğini önemsemeden alır ve işler böylece sistemimiz daha güzel bir mimariye sahip olmuş olur. Sistemin bileşenleri arasında bağımlılık en aza indirilmiş olur. Keyword: decoupling

   

Azure Queue'da mesaj aynı anda sadece bir alıcıya ulaşır. Yani eğer sizin iki tane worker role'unuz var ve aynı kuyrugu kontrol ediyorsa bunlardan biri mesajı alır ve diger alamaz. Birbirlerinden mesajları çalarak ilerlerler. Eğer sisteminizde bir worker role yetmiyorsa ikinci worker role'u eklerseniz sisteminizin çalışma hızı yaklaşık 2 ye katlanmış olur. Eğer mesajların aynı anda iki worker role'ede iletilmesini istiyorsanız Service Bus'ı kullanmayı düşünmelisiniz.

Microsoft Azure Kişisel İzleme Projesi: RescueTime

Yapmak istediğim şey şu şekilde, Azure üzerinde bir TableStorage olacak, hakkımdaki bazı bilgileri orada saklayacağım mesela günde %kaç üretkenlikle yaşıyorum :), kaç adım atıyorum vs. Bunun için biraz extensible bir yapı kurmaya çalışacağım. Bu blogda konu RescueTime,

   

Bir software var adı RescueTime. Bu uygulamanın bir chrome extension'i var birde desktop uygulaması, yaptığı asıl iş şöyle; bilgisayarınızda ve browserinizda kullandığınız uygulama ve websitelerini takip ediyor ve bir takım istatistikler sunuyor. Bence çok faydalı bir uygulama, bu uygulamadan Daron Yöndem hakkında bir kaç yıl önce haberdar olmuştum. İlgili blog yazısına buradan ulaşabilirsiniz. Daron Yöndem'in blog yazısı aslında uygulamayı çok iyi bir şekilde anlatıyor, tekrar yapmaya gerek yok.

RescueTime'in birde api'i mevcut, oldukça kolay kullanıma sahip ve bize json olarak bir takım veriler sunmakta. https://www.rescuetime.com/developers adresinden detayları öğrenebilirsiniz. Kısaca bir key yaratıyorsunuz ve api'a http request yaparak json sonuclari alıyorsunuz. Şahsi görüşüm api çok başarılı değil ama iş görüyor.

   

Ben bu api'dan bilgileri alıp, Azure Storage table'a yazmak istiyorum. Bunun için bir Azure WebJobs yaratacağım ve bu günde bir kaç kez çalışarak rescuetime api'i ile konuşacak ve sonuçları Azure Table Storage'a kayıt edecek. Henüz planlamamış olsamda daha sonraki blog yazılarımda bu veriyi değişik şekillerde kullanacağım. Mesela blog üzerinde gösterebiliriz. (Sağ tarafta göreceksiniz.)

   

Solution açıyoruz ve içinize bir kaç tane proje ekliyoruz. Amacimiz biraz güzel bir yapı kurmak. Bugun rescue time verilerini loglamaya çalışacağız ancak yarın Fitbit vs. gibi başka kaynaklarla kendimize özel bilgileri loglayabileceğimiz bir sistem olsun istiyorum. Kaynak kodları indirmek için postun altında github linki bulabilirsiniz.

   

Solution Explorer

   

Projeleri tanıtalım:

  1. PersonalTracking.StorageRepository: Bu proje aslında bir class library ve amacimiz Azure Storage Table ile iletişim kurmak.
  2. PersonalTracking.Web: Bir web projesi, basit bir arayüz ile şimdilik verileri gösterebiliriz.
  3. PersonalTracking.WebJob: Bir web job projesi, belirlediğimiz aralıkta çalışacak ve istediğimiz işleri yapacak.

       

    WebJob projesinden başlayalm; yapmak istediğim çok basit bir Factory Pattern, IEngine isimli bir interface olacak ve içinde bir start methodu bulunacak.

       

    IEngine.cs
     

    Birde factory olacak, uygun engine'i döndürecek ve dinamik olarak Start methodunu çağıracağız.

       

       

EngineFactory.cs

   

Gördüğünüz üzere kod yeni başlayan arkadaşlara biraz standart dışı gelebilir. Reflaction vs birşeyler yazıyoruz ve IEngine'i implement alan tüm class'lari bize IEnumarable olarak geri döndürecek.

   

Eee yazdıkda ne oldu. Bunları WebJob üzerinden çağırmamız lazım. Geri dönen Ienumarable<IEngine> içindeki her instance için tek tek Start() methodu çağırılmalı.

   

Functions.cs

   

Gördüğünüz gibi listedki tüm instance'larin Start() methodunu invoke ettik.

   

RescueTimeEngine.cs

RescueTimeEngine class'i IEngine implement eden bir class ve amaci rescue time api'i ile konuşup. Verileri storage'a göndermek hatırlarsanız StorageRepository bizim Azure Storage işlerimizin yürüdüğü katmandı diyebiliriz.

   

Ve işlem aslında bukadar artık veriler table storage'a kayıt ediliyor.

   

RescueTimeLogs Table

   

Gördüğünüz gibi loglarımızı TableStorage'a kayıt ettik.

   

Devamında Fitbit engine yazarak konuya devam edeceğiz.

   

Kodlar: https://github.com/altinokdarici/PersonalTracking