Bugünün konusu olarak belki duyduğunuz, belki de çoktan büyük ölçekli uygulamalarınızda kullandığınız Hangfire kütüphanesinden bahsedeceğim. Hadi başlayalım. (Kaynak kodu : Github)
Hangfire Nedir?
Background job’ları (arka plan işleri) yaratmanıza, yürütmenize ve yönetmenize kolaylık sağlayan açık kaynaklı kütüphanedir. Job storage olarak bir çok veritabanı (SQL Server, SQL Server + MSMQ, Redis ve daha fazlası), IoC Container ve Unit Test desteklemektedir. Listesi için Hangfire Extension sayfasına göz atabilirsiniz. Hangfire Sidekiq, Resque ve Celery uygulamalarına .NET alternatifidir.
Background Job Nedir?
Bazı kodların arka planda çalışması gerekmektedir. Çünkü bir iş parçacığının ana thread’de çalışması hem doğası gereği hem de bazı ihtiyaçlar dahilinde uygun olmayabiliyor.
Hangfire Kullanımının Artıları
- Kullanımı kolay, bir kaç satırla tüm .NET uygulamalarınızda çalıştırabilirsiniz,
- Yönetilebilirlik ve görünebilirlik sağlar,
- İşler veritabanında tutulduğu için güvenilirdir. İş tamamlanmadıkça tamamlandı durumuna geçmez, kod bloğunun bitimine kadar çıkacak herhangi bir sorunda iş tekrar çalışacaktır,
- Uygulamanızdan farklı, dağıtık şekilde kullanılabilir (Infrastructure).
- ASP.NET uygulamalarında yaşanan sorunlara çözüm sağlar
- Uzun süren request thread’ler,
- Birden fazla yaratılmış background job instance’ı (aynı işin aynı zamanda yapılabiliyor olması sorunu),
- IIS’in AppDomain ve App Pool recycle etmesi (Background job’ların yarım kalması ve tekrarlanmaması).
Hangfire’ın Desteklediği Background Job Tipleri
- Fire and forget : Bir kere ve hemen çalışan background job tipi
- Delayed : Bir kere fakat belirtilen sürenin sonunda çalışan background job tipi
- Recurring : Çok kez ve belirtilmiş CRON sürecinde (günlük, saatlik, haftalık veya CRON expressions vb.) çalışan background job tipi
- Continuations : Tanımlanan ana işin bitiminde çalışan background job tipi
- Batch (PRO) : Birden fazla işin grup halinde çalışan background job tipi
- Batch Continuations (PRO) : Grup halinde çalışan ana background job’ın bitimiyle çalışan background job tipi
NOT : PRO olarak ifade edilen background job tipleri Hangfire’ın ücretsiz sürümünde yer almamaktadır. Yıllık ücret karşılığında bu background job’lara erişilebilir. Ücretlendirme ile ilgili bilgilere ulaşmak için Hangfire Pricing ekranına göz atabilirsiniz. (Ek olarak : Compleks iş akışları, Redis depolama desteği, performance counter işlemleri)
Hangfire Kurulum ve Konfigürasyon
Hangfire’ı kullanmak istediğiniz projenize Nuget Package Manager yoluyla veya komutla Hangfire’ı yükleyin.
Komut : PM> Install-Package Hangfire (Nuget)
NOT : Farklı proje tipleri için farklı paketler yüklemeniz gerekebilir. Örneğin console uygulaması için Hangfire.Core yüklemeniz lazım fakat IIS’de host edilen web uygulaması için Owin de yüklenmelidir (dependency => Hangfire). Yükleme ve paket ile ilgili bilgiler için Hangfire Installation sayfasına göz atabilirsiniz.
Aşağıda paylaştığım konfigürasyon örneği (en basit haliyle), ASP.NET MVC projesidir.
NOT : Batch kullanmak istiyorsanız ekstradan “GlobalConfiguration.Configuration.UseBatches()” satırını eklemeniz gerekiyor.
Hangfire yaratılan job’ları veritabanında tutar, tamamlandıkça da kendisi siler. Veritabanını kendisi yaratmıyor fakat gerekli tabloları kendisi oluşturuyor. (Uygulamanızın veritabanı ile Hangfire veritabanı farklı olabilir.)
Uygulamayı çalıştırdığınızda tabloların oluştuğunu göreceksiniz.
Hangfire dashboard’a ulaşmak için uygulamanızın URL’inin sonuna “/hangfire” yazmanız yeterli.
Hangfire Entegrasyonu
Hangfire’ı uygulamanızda kullanırken uygulayabileceğiniz bir kaç farklı senaryo var.
- Single Process
- Web Garden
- Web Farm
- Seperate Service
- Seperate Server
Hangfire Parametre İşlemleri
- Çoklu parametre desteği var
- Parametreler serialise (JSON) edilip veritabanında tutuluyor (Array, collection, custom object)
- Referans parametre ve ref ve out keyword’leri için desteği bulunmamaktadır
- Tüm kayıt yerine Id gibi belirgin değerin tutulması tavsiye edilir. Sebebi ise job storage’da tutulacak kaydın boyutu daha küçük olması
Hangfire Dashboard
Hosting
- OWIN Middleware olarak yazılmıştır
- ASP.NET, Nancy ve ServiceStack
- OWIN Self Host
- Console uygulaması ve Windows Service
- Gereklilikler
- Microsoft.Owin.Host.SystemWeb
- OWIN Startup class
- app.UseHangfireDashboard() konfigürasyon kodu
Sunduğu Özellikler
- Servers (sunucular) : Kullanılan Hangfire sunucuları ve bilgilerini (name, workers, queues, başladığı an ve en son çalıştığı an vs.) gösterir
- Recurring Jobs : Yaratılan recurring job bilgilerini gösterir. Bunlar : Cron, Time Zone, Job, ne zaman çalışacağı, en son ne zaman çalıştığı ve yaratıldığı tarih. Ayrıca, her ne kadar belirli bir tarih tanımlanmış olsa da Trigger özelliği ile istenilen an tetiklenebilir.
- Retries (tekrar) : Yaratılan job’ların hata alması durumunda job’ların gösterildiği ekrandır. Kaç kere denendiği de görülebilir. Default olarak atanmış deneme (retry) sayısı 10’dur.
- Jobs (işler)
- Enqueued : Sırada olan işler,
- Scheduled : İleri tarihe ayarlanmış işler,
- Processing : Çalışan işler,
- Succeeded : Başarılı şekilde tamamlanmış işler,
- Failed : Başarısız olmuş işler (tanınmış atama sayısından sonra bile hata alınıyorsa iş buraya düşer),
- Deleted : Silinmiş işler,
- Awaiting : Sırasını bekleyen (continuations) işler.
Hangfire Dashboard Gelişmiş Konfigürasyon Seçenekleri
Hangfire Dashboard URL değişikliği ve geri yönlendirme opsiyonu
Birden fazla Hangfire Dashboard (ve/veya farklı veritabanları) kullanımı
Hangfire Dashboard Güvenlik
Hangfire Dashboard’a default; local olarak erişilebilir. Örneğin sunucuda IIS’de çalışan bir web uygulamanızın Hangfire Dashboard’una remote (uzaktan erişim) makineden erişemezsiniz. Fakat uzaktan erişim için yetki vermeniz mümkün. Bunun için (IAuthorizationFilter 2.0.0 ile silinecek) IDashboardAuthorizationFilter interface‘ini kullanmanız gerekiyor.
Daha fazla bilgi için => http://docs.hangfire.io/en/latest/configuration/using-dashboard.html#configuring-authorization
Hangfire Exception
Hangfire, uygulamanızda alacağınız hataları (default tekrar deneme sayısı : 10) hata detayı ile birlikte gösterir. Hata aldığınız job, retries sekmesine düşer. Retry sayısını Global ve Method seviyesinde değiştirmek mümkün. Örneğin retry sayısını 1 yaparsanız 1. denemeden sonra tekrar hata alınması durumunda job Failed sekmesine düşecektir.
Global seviyede retry sayısını değiştirmek için aşağıdaki kodu kullanabilirsiniz.
Method seviyesinde değiştirmek isterseniz, methodunuza aşağıdaki attribute’u ekleyebilirsiniz.
[AutomaticRetry(Attempts = 1)]
Eğer fail olan joblarınızın manuel değil de otomatik olarak silinmesini istiyorsanız
AutomaticRetry(OnAttemptsExceeded = AttemptsExceededAction.Delete) kodunu kullanabilirsiniz.
Daha fazla bilgi için => http://docs.hangfire.io/en/latest/background-processing/dealing-with-exceptions.html
HangFire Logging
Hangfire otomatik loglama desteğine (Serilog, NLog, Log4Net, EntLib Logging, Loupe ve Elmah) sahiptir. Otomatik loglama; startup sınıfında log provider tanımlamanızın yettiği anlamına geliyor. Ayrıca custom loglama desteği (ILogProvider, ILog) de mevcuttur.
Daha fazla bilgi için => http://docs.hangfire.io/en/latest/configuration/configuring-logging.html
HangFire SQL Server Ayarları
Daha fazla bilgi için => http://docs.hangfire.io/en/latest/configuration/using-sql-server.html
NOT : Hangfire, Redis desteklemektedir. Redis’in tercih sebepleri arasında yüksek performans (in-memory) ilk sıradadır fakat Redis kullanmak için Hangfire PRO yani ücretli versiyonu kullanılması zorunludur. Daha fazla bilgi için => http://docs.hangfire.io/en/latest/configuration/using-redis.html
Ve son olarak dikkat edilmesi gerekenler…
- Job’ları kullandığınız metotlar yarıda kesilebilir ve tekrarlanabilir,
- Methodlarda kullandığınız parametreler, kompleks olmayan (basit), küçük ve object yerine primitif tip,
- Unit test ve IoC’ye uygun,
- Job takibi Polling vs. Pushing (örnek : SignalR) ayrımı gözetilerek
yazılırsa kodunuz optimize olmuş olur.