Asp.Net Core Hangfire Kullanarak Background Task İşlemleri

Projelerimizde olağan akışında ilerlerken veya bir business rule çalışırken mevcut akışı durdurmadan asenkron bir şekilde uygulamadan bağımsız çalışmasını istediğimiz process'ler olmuştur. Bu gibi ihtiyaçları karşılaması için Azure olsun Google-Cloud yada Amazon olsun kendi cloud çözümlerini üreterek kullanmamıza olanak sağlamaktadırlar.

Peki ya on-premise dediğimiz kurum içi yada domain içi çözüm olarak neler yapabiliriz ? Fire-and-forget (messaging queue) yapılarından birini kullanabilir veya mevcut uygulamada background job'lar üretebiliriz.

Bu yazımızda Asp.net Core uygulamalarında Hangfire kullanarak background-task'lar nasıl oluşturulur inceleyeceğiz.

Hangfire 

Özetle; open-source olarak geliştirilmiş schedule edilebilen process'lerin kolay bir şekilde yönetimini sağlayan bir kütüphanedir. Sahip olduğu dashboard ile job'larınızı historical olarak görüntüleyebilir, start-stop/restart gibi işlemler yapabilirsiniz.

An easy way to perform background processing in .NET and .NET Core applications. No Windows Service or separate process required.

Hangfire job'ları yönetirken storage alanı olarak hemen hemen bütün database türleri için destek sağlamaktadır. SQL Server, Redis, PostgreSQL, MongoDB etc.

İlk olarak uygulamamızda kullanmak üzere local Sql Server üzerinde Hangfire adında bir databse oluşturalım.

Sonrasında Vs.'da BackgroundTaskWithHangfire adında bir Api projesi oluşturalım ve nuget üzerinden bugün için en güncel olan Hangfire v1.6.20 paketini projemize ekleyelim. 

PM> Install-Package Hangfire

İlk başta oluşturduğumuz database'in conn string bilgilerini appSettings.json dosyasına ekleyelim.

  "HangfireDbConn": "Server=.;Initial Catalog=Hangfire;Persist Security Info=False;User ID=HangfireUser;Password=qwerty135*;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;"

Sırada uygulama üzerinde hangfire configuration'ı var. Bunun için Startup.cs de bulunan ConfigureServices metodu içerisinde Hangfire'ı service olarak ekleyelim ve sonrasında Configure metodu içerisinde bu service'i kullanacağımızı belirten kod bloklarını yazalım.

public void ConfigureServices(IServiceCollection services)
{
    services.AddHangfire(_ => _.UseSqlServerStorage(Configuration.GetValue<string>("HangfireDbConn")));
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseHangfireDashboard();
    app.UseHangfireServer();
}

Yukarıdaki kod bloğunda hangfire storage bilgisini vererek uygulamamız service'lerine register ettik ve devamındada hangfire'ın server ve dashboard service'lerini kullanacağımızı belirttik.

Hangfire dashboard default olarak uygulamanın çalıştığı portta' http://<application>/hangfire adresinde host edilir. Bizde localhostta çalıştığımızdan uygulamayı run edip browser üzerinden http://localhost/hangfire adresine gittiğimizde aşağıdaki gibi hangfire dashboard'u görüntüleyebiliriz.

Dashboard'la birlikte uygulama her start olduğunda db'de ilgili tablolar oluşmuşmu diye check ederek oluşmadıysa tabloları oluşturur. Hangfire tablolarını sql server management studio üzerinden görüntüleyebilirsiniz.

 

Hangfire konfigurasyonunu tamamladık şimdi sırasıyla Hangfire kütüphanesinde bulunan BackgroundJob sınıfını kullanarak oluşturabileceğimiz job türlerine bakacak olursak;

1- Fire-and-Forget Jobs

            Job create edildikten sonra çalışır ve process olur.

public class FireAndForgetJob
{
    public FireAndForgetJob()
    {
        //Fire and forget
        var jobId = BackgroundJob.Enqueue(() => ProcessFireAndForgetJob());
    }

    public void ProcessFireAndForgetJob()
    {
        Console.WriteLine("I am a Fire and Forget Job !!");
    }
}

2- Delayed Jobs

            Belli bir zaman bilgisi set edilerek sadece bir kez çalışmasını istediğimiz task'lar için kullanabileceğimiz job türü. Aşağıdaki gibi Job register olduktan 4 dkka sonra çalışacaktır.

public class DelayedJob
{
    public DelayedJob()
    {
        //Delayed job
        var jobId = BackgroundJob.Schedule(() => ProcessDelayedJob(), TimeSpan.FromMinutes(4));
    }

    public void ProcessDelayedJob()
    {
        Console.WriteLine("I am a Delayed Job !!");
    }
}

3- Recurring Jobs

            Recurring yani tekrar eden task'lar için kullanılan job türü. Örneğin; her saat başı çalışmasını istediğiniz bir job'a ihtiyacınız olduğunda aşağıdaki gibi tanımlayabiliriz.

public class Recurring_Job
{
    public Recurring_Job()
    {
        //Recurring job
        RecurringJob.AddOrUpdate(() => ProcessRecurringJob(), Cron.Hourly);
    }

    public void ProcessRecurringJob()
    {
        Console.WriteLine("I am a Recurring Job !!");
    }
}

4- Continuations Jobs

            Parent-child ilişkisinin olduğu yani bir job'ın çalışması için başka bir job'ın tamamlanmasını bekleyip o Cmplete olduktan sonra çalışmasını istediğimiz işler için kullanabileceğimiz job türü.

public class ContinuationsJob
{
    public ContinuationsJob()
    {
        //Delayed job
        var parentJobId = BackgroundJob.Schedule(() => Console.WriteLine("I am a Delayed Job !!"), TimeSpan.FromMinutes(4));


        //Continuations job
        BackgroundJob.ContinueWith(parentJobId, () => ProcessContinuationsJob());
    }

    public void ProcessContinuationsJob()
    {
        Console.WriteLine("I am a Recurring Job !!");
    }
}

Projeyi run edip tekrardan  http://localhost/hangfire adresine gittiğimizde ilgili job türlerine ait bilgileri dashboard'da görüntüleyebiliriz.

Özetlemek gerekirse; uygulamanızda çalıştırmanız gereken background-task'ları için Hangfire implementasyonunu hızlı bir şekilde yapıp dashboard'u ile birlikte kolayca kullanabilirsiniz. Eğer .net core'un kendi background task sınıfını kullanarak ilerlemek isterseniz hangfire'a göre daha zorlu bir süreç sizi bekliyor olacaktır. Hem yönetilebilirlik açısından hemde visualization olarak hangfire kesinlikle sizin için daha sorunsuz ve kullanışlı bir çözüm olacaktır. Hangfire'ın muadili olan Quartz.net veya bir queue çözümü de kullanarak işlemlerinizi yapabilirsiniz.

Source Code

Comments (6) -

  • Hocam Hangfire kullanarak geliştirdiğim bir web uyg. Canlıya nasıl çıkarım. Kodu sunucuya çıktığım andan itibaren hazırladığım görevler zamanı geldiğinde otomatik çalışacak mı? Yoksa benim web sayfamı tetiklemem mi gerekir.
    Saygılarımla.
    • Eğer job'ları start eden kod bloğu uygulama ayağa kalkarken çağrılıyorsa uygulaa run olduğ  gibi job'lar schedule olacaktır.
  • Merhabalar hangfire ile iki tarih aralığında bir işin  belli periyotlarla çalışmasını sağlayabiliyor muyuz?
    örnek: 02-06-2021 ile 07-06-2021 arasında  saatte bir çalışan job
  • Merhabalar,
    Birşey sormak istiyorum ;
    RecurringJob ile belirli zamanlara bir süreç için çalıştırmak istiyorum fakat bu jobu kendim çoğaltmadan n tane olacak şekilde bir kullanımı oluyor mu acaba ?
    Örneğin ;
    3 tane lokasyonum var hangfire job ile belirli zamanlar her lokasyon için belirli dataları almak istiyorum fakat her lokasyon için aldığım datayı farklı dblere yönlendirme yapmak istiyorum. Fakat bunun için  3 tane job yazmak yerine bir tane yazarak bunu dashboard üzerinde her  lokasyon için yapılan işlemi ayrı ayrı görebilecek şekilde ayarlama yapailiyor muyuz ?
  • hangfire server kurulumu anlatılmış hangfire server için bir proje olusturdugumuzda farklı bir projeden hangfire jobs atma olayı yanı client olayını nasıl yapmamız gerekiyor iki proje birbirinden bagımsız oldugunda hangfire tarafına job atılırken diğer projeye de hangfire server gibi yapılandırma yapılması mı gerekiyor

Add comment