WebJobs Giriş ve Bloblarla Kullanımı

0 dakikada yazıldı

63508 defa okundu

Düzenle

Azure tarafında uzun yıllardır en sıkıntılı konulardan biri ScheduledService'ler. Aslında sıkıntı da zaten bu gibi zamanlanmış servislerin oluşturulması için tabiri caiz ise adam gibi bir altyapının olmaması. Tabi ki isterseniz bir VM alıp "Windows Scheduler" kullanabilirsiniz veya Cloud Service'inize bir worker ekleyip işi çözebilirsiniz ama bu çözümlerden biri PAAS çözümü değilken diğeri ise basit bir Scheduler için çok maliyetli. Bu yazıda bahsedeceğimiz WebJobsSDK bu sorunu çözmeyi amaçlarken kendisi de Preview'da olan WebJobs konsepti ile Azure Web Sites üzerinden sunuluyor. Şu an için Preview olmasından dolayı çok eleştirel yaklaşmayacağım fakat WebJobs'ı nasıl kullanırıza gelmeden önce bilmeniz gereken birkaç şey var. İlk olarak bu servisin Azure Web Sites altında gelmesi manidar. WebJobs şu anda Cloud Service'daki ölçeklenebilirlik ihtiyaçlarınızla paralel yükleri kaldırabilecek nitelikte değil. Azure Web Site deploymentınızın boyutu bugün neyse WebJobs'da aynı kaynaklarda çalışıyor ve kaynakları paylaşıyor. Yani ayrıca scale etme vs şansınız yok. Cloud Service'ler için şu anda daha low level bir implementasyon sunan Azure Scheduler'ı tavsiye edebilirim. Zaten her iki servisin adındaki farklılık da çok anlamlı. Biri Scheduler biri Job :) Yani sonuç itibari ile Job'ları da schedule edebiliyoruz ama WebJobs çok daha yüksek seviyeli, Azure Web Sites'a uygun bir altyapı sağlayarak çok daha kolay kullanımlı bir ortam sağlıyor. Konsept üzerinden konuşmayı bu noktada bırakıp gelin Webjobs SDK ile neler yapabiliyoruz görelim.

WebJobsSDK

WebJobs üzerinden bir çok senaryo ilerletmek mümkün. Ben .NET tarafına odaklanacağım ama Bash, PHP, Node, Python veya basit BAT dosyları ile de Job yazabilirsiniz. .NET tarafında yazdığımız Job'ı bir "Console Application" olarak tasarlayacağız ve sağladığı kolaylıklardan da faydalanmak için WebJobsSDK'i referans olarak projemize ekleyeceğiz. Yeni bir konsol uygulaması yarattıken sonra SDK'in Preview Nuget paketlerini indirmek için Nuget Package Manager Console'da aşağıdaki komutları çalıştırabilirsiniz.

Install-Package Microsoft.WindowsAzure.Jobs -Pre

Bu komutları çalıştırdığında projenize dört tane referans eklenecek. AzureConfiguration, StorageClient, Jobs ve JobsHost adındaki bu referansların ikisi doğrudan JobsSDK ile alakalı iken diğer ikisi ise JosbSDK'in doğrudan Azure'daki Storage Servislerini kullanmak zorunda olmasından kaynaklanıyor. Yanında bir de JSON.NET gelecektir. Onun da ileriki makalelerde JobsSDK'in Storage'lardaki Queue'lar ile olan ilişkisine bakarken hep beraber göreceğiz :)

Blob üzerinden "Trigger" ve "Output"

Ortamımız hazır olduğuna göre artık kod yazmaya başlayabiliriz. Yapacağımız uygulamanın iki bölümü olacak. WebJobsSDK'i kullanarak harici bir Storage Account içerisindeki bir Blob Container'ın içine dosya konduğu anda kendi tanımlayacağımız bir işlem yapmak istediğimizi varsayalım. Örneğin ben özel bir container'a bir text dosyası konduğunda içindeki metni küçük harflere çevirerek başka bir containera yeni bir text dosyası olarak kopyalamak istiyorum. Bunun tamamen otomatik olarak WebJobs tarafından sürekli yeni bloblar için yapılmasını istiyoruz. Tabi böyle saçma bir örnek vermemin nedeni örneği basit tutabilmek ama siz daha karmaşıklarını hayal edebilirsiniz. Örneğin bir container'a konan resimleri resize etmek güzel bir senaryo olabilir.

[C#]

class Program
{
    static void Main(string[] args)
    {
        JobHost host = new JobHost();
        host.RunAndBlock();
    }
    public static void LowerCase(
        [BlobInput(@"gelenblobcontainer/{name}")] Stream gelenStream,
        [BlobOutput(@"gidenblobcontainer/{name}")] Stream gidenStream)
    {
        string tumMetin = "";
        using (StreamReader st = new StreamReader(gelenStream))
        {
            tumMetin = st.ReadToEnd();
        }
        using (StreamWriter stw = new StreamWriter(gidenStream))
        {
            stw.Write(tumMetin.ToLower());
        }
    }
}

Yukarıdaki kafa karıştırabilecek bir çok şey var. O nedenle gelin adım adım ilerleyelim. Konsol uygulaması ilk çalıştığında JobHost adında bir nesne yaratıp RunAndBlock ile Host'u çalıştırıyoruz. Bu noktada WebJobs'a bizim konsol uygulaması ile tüm jobların çalışması gerektiği mesajını vermiş olduk. Sonrasında hemen altta ise LowerCase diye bir metod var. Bu metodun parametrelerinde bir anlamda "Model Binding" mevcut. BlobInput ve BlobOutput için verdiğiniz değerler doğrudan container adı üzerinden giden ve takip etmek istediğiniz Blobların adresini tanımlayan path değerleri. {name} keyword'ü blobun kendi adını temsil ediyor. Böylece benim storage account'um içerisindeki containerlardan "gelenblobcontainer" adındaki container içindeki bloblar takip edilecek ve bu blobların içeriği doğrudan Stream olarak gelenStream'e atanacak. Aynı işlem OutputBlob ile de Storage Account'a geri blob atmak için kullanılacak. OutputBlob için ben farklı bir container kullandım. Blob ismi olarak ilk gelen InputBlob'un ismini atadım. Bu noktadan sonra gidenStream'e her ne yazarsam yaziyim OutputBlob'a verdiğim path çerçevesinde Storage Account'ta bir blob'a yazılacak. Geri bize geri kalan da gelen Stream'i okuyup istediğimiz değişiklikleri yapıp OutputStream'e son hali yollamak.

Gördüğünüz üzere WebJobs SDK süper bir implementasyona sahip. Neredeyse tün Blob kullanımına dair karışıklıkları çözüp atıyor. Peki hangi StorageAccount'u kullanacağını nasıl biliyor derseniz işte onu da tabi ki Web.Config'den alacak. Bunun için Azure Web Sites'ın yönetim paneline gidip iki farklı Connection String tanımlamamız gerek.

Webjobs'a özel iki Connection
String.

Yukarıdaki ekran görüntüsüne de görebileceğiniz üzere Azure Web Site'ımızın Connection String'lerine iki adet yeni item ekliyoruz. Bunlardan "AzureJobsData" doğrudan bizim kullanacağımız verilerin bulunduğu Storage Account'un Connection Stringi. Örneğimizdeki "gelenblobcontainer" bu Storage Account'un içerisinde olacak. Diğer Connection String ise AzureJobsRuntime'ın kullanacağı ve kendi loglarını tutacağı yer. Her iki connection string de aynı Storage Account'u hedefleyebilir. O konuda bir sıkıntı olmayacaktır. Runtime Logging için WebJobsSDK iki adet ek container yaratacak. Bunlar "azure-jobs-invoke-log" ve "azure-jobs-event-queue" şeklinde. Umuyorum ki sizin aynı isimde containerlarınız yoktur :) Bu containerların içinde sistem kendi loglarını tutuyor.

WebJobs'ın loglarından bir
örnek.WebJobs'ın loglarından bir örnek.

Tabi bu logları tek tek text dosyalarını açarak incelememize gerek yok. Bunun için Azure Web Sites altında bir Extension olarak çalışan özel bir Dashboard var. Dashboard'a ulaşmak için https://SITENIZINADI.scm.azurewebsites.net/azurejobs/ adresine gitmeniz gerekiyor. Deployment Credential'larınızı kullanarak buraya giriş yaptığınız anda inanılmaz güzel detayları görebilmeye başlayacaksınız.

WebJobs
Dashboard'u.WebJobs Dashboard'u.

Bu Dashboard içerisinde sadece WebJobs Host'unuzu yaşam döngüsünü değil tek tek yapılan işlerin detaylarını bile görebilirsiniz. Özellikle birden çok Job'ınız olduğunu düşünürsek buradaki loglar debugging için de süper bir değere sahip.

Dashboard'un detaylarında neler
saklı...Dashboard'un detaylarında neler saklı...

Blobların aynı sıra WebJobs Azure Storage'daki Queue ve Table servisleri ile de çalışabiliyor. Bunların detaylarına ileriki yazılarda göz atacağız. Şimdilik isterseniz bir de gelin yukarıdaki tüm hikayesine göz attığımız örnek WebJob projemizi Azure'a nasıl deploy edeceğimize bakalım. :) O konuyu atladık.

Deployment

Elinizdeki Konsol uygulamasını deploy etmek için her şeyi alıp bir ZIP haline getirmeniz lazım. Bu ZIP'i doğrudan Azure Management portalından upload edeceğiz. Management Portal içerisinde kullanacağınız Web Site'ın detaylarına girdiğiniz en üst kısımda WebJobs tabını göreceksiniz. Oraya girip yenib ir Job yaratmak istediğinizde sizden Job için bir isim, çalışma şekli ve ZIP dosyası istenecek.

Farklı WebJob
seçenekleri.Farklı WebJob seçenekleri.

Biz örneğimizde "Continious" seçeneği kullanmalıyız ki sürekli olarak yeni bir Blob geldiğinde Job'ımız çalışsın. Bu arada Blob'lardaki değişiklikler ortalama 10 dakikada bir kontrol ediliyor. Malum ne kadar sürekli takip et desek de Storage servislerine bir REST call gitmesi lazım. WebJobs için diğer seçeneklerden biri "On Demand". Bu durumda gelip portaldan Job'ın çalışmasını tetikleyebilirsiniz veya JobHost nesnesine erişimi olan herhangi bir yerden JobHost'un Call metodunu da çağırabilirsiniz.

Olayın biraz daha derinlerine inersek aslında Upload ettiğiniz ZIP dosyası doğrudan sitenizde "site\wwwroot\App_Data\jobs\{job tipi}\{job adı}" şeklinde bir pathe extract edilecektir. Job Tipi "Continuous" veya "triggered" olabilir. Hem scheduled hem de On Deman joblar "Triggered" olarak geçiyor. Dosyalarda herhangi bir değişiklik olduğunda sistem ilk olarak "run" adına sahip ve WebJobs tarafından desteklenen uzantılarda bir dosya arayacak. Eğer WebJobs bu gibi bir dosya bulabilirse çalıştıracak aksi halde desteklenen uzantılardaki tüm dosyalara bakacak.

Böylece WebJobs'ın sadece genel kullanımına değil Blob'larla nasıl kullanılabileceğine de göz atmış olduk. İleriki bir yazıda Queue ve Table servisleri ile WebJobs kullanımını da inceleyeceğiz.

Makaledeki örneği Github üzerinden indirebilirsiniz.