Dayanıklılık ve gözlem
Arka plan işleri ve kuyruklar
Kullanıcıyı bekletmemesi gereken işleri istek yolundan çıkarmak.
Kavramı anlayalım
Bazı işler kullanıcının yanıt beklediği süreye sığmamalıdır: e-posta göndermek, görsel küçültmek, rapor üretmek, sosyal medyada paylaşmak. Bu işler istek içinde yapılırsa yanıt yavaşlar ve dış servisin arızası kullanıcının işlemini de başarısız kılar. Çözüm, isteğin yalnız ‘işi kaydetmesi’ ve asıl işin arka planda yapılmasıdır.
ASP.NET Core’da BackgroundService, uygulamayla birlikte başlayan uzun ömürlü bir döngüdür. Basit bir kuyruk (Channel) ile istek işi kuyruğa koyar, arka plan servisi alıp işler. Ancak bellek içi kuyruk, uygulama yeniden başlarsa içindeki işleri kaybeder. Kaybolmaması gereken işler kalıcı bir yere yazılır: veritabanında bir ‘outbox’ tablosu veya bir mesaj kuyruğu (RabbitMQ, Azure Service Bus).
Outbox deseni önemli bir sorunu çözer: veritabanı kaydı ve ‘e-posta gönder’ işi aynı transaction içinde outbox tablosuna yazılır. Böylece kayıt başarılı olup e-posta işinin kaybolması veya tersi olmaz. Arka plan işi outbox’ı okuyup gönderir ve başarılı olanları işaretler. Bu projenin yayın otomasyonu ve sosyal paylaşım günlükleri de benzer bir mantıkla, başarısızları yeniden denenebilir tutar.
Yavaş veya güvenilmez işler kullanıcı deneyimini ve veri tutarlılığını bozmamalıdır.
Task.Run ile istekten ‘ateşle ve unut’ iş başlatmak; istek bitince kapsam ve DbContext yok olur, hatalar kaybolur.
Aynı konu. Üç farklı derinlik.
// İstek: yalnız kaydet ve hemen yanıt ver
await db.Messages.AddAsync(message, ct);
await db.SaveChangesAsync(ct);
return Accepted(); // 202: kabul edildi, işlem sürüyor202 Accepted, işin alındığını ama henüz tamamlanmadığını anlatır.
Bu sayfa gerçek bir sunucuya veya veritabanına bağlanmaz. Kod örnekleri .NET 8, Next.js ve SQL Server için temsilîdir; süreler simülasyondaki örnek değerlerdir, ölçüm değildir. Örnekleri yalnız kendi geliştirme ortamında dene; gerçek bağlantı dizesi, token veya parola paylaşma.
Önce kendin dene.
İletişim formu gönderildiğinde mesaj kaydediliyor ve sana e-posta atılıyor. SMTP sunucusu 10 saniye yanıt vermediğinde kullanıcı ‘hata’ görüyor ama mesaj veritabanına kaydedilmiş oluyor. Nasıl yeniden tasarlarsın?
Çözümü ve açıklamasını göster
1) İstek: mesajı + 'bildirim gönder' işini aynı transaction’da yaz (outbox), hemen 201/202 dön.
2) Arka plan işi: outbox’tan alıp e-postayı gönderir; hata olursa artan aralıklarla tekrar dener.
3) Kullanıcı yalnız kendi işleminin (mesajın kaydı) sonucunu görür.Kullanıcının işlemi ile yan etkiler ayrıldığında, dış servisin arızası kullanıcıya yanlış bir hata olarak yansımaz.