Yedi e-posta: yinelenen mesajlar teorik bir sorun değil
Mauro Servienti, bir sipariş bildiriminin yedi kez gelmesi üzerinden mesajlaşma sistemlerinde yinelenen mesajların nasıl oluştuğunu anlatıyor. Yazı; gönderim, alım ve işleme tekrarlarını ayırıyor ve her biri için pratik önlemler sunuyor. Kuyruk tabanlı sistem kuran her .NET geliştiricisinin okuması değerli.
Kilit noktalar
- Yinelenen mesajlar üç durumda oluşur: gönderim, alım ve işleme; her birinin nedeni ve çözümü farklıdır.
- Gönderen tarafta SetMessageId ile tetikleyiciden türetilmiş kararlı bir mesaj kimliği kullanmak tekrarları ayırt edilemez hale getirir.
- Outbox deseni, iş verisi ile giden mesajları aynı transaction içinde saklayarak atomik olmayan toplu gönderim sorununu çözer.
- Alıcı tarafı idempotent yazılmalı; mesaj kimliği tabanlı deduplikasyon yalnızca kimlikler aynıysa işe yarar.
- E-posta ve ödeme gibi yan etkiler için en fazla bir kez ya da en az bir kez arasında bilinçli bir seçim yapılmalı; ödeme sağlayıcılarında idempotency key kullanılmalı.
Yinelenen mesaj, dağıtık sistemlerde bir mesajın bir kez değil birden fazla kez gönderilmesi, alınması veya işlenmesi anlamına gelir. Yazar bunu bir bisiklet pedalı siparişinin yedi kez gelen e-postasıyla somutlaştırıyor. Bir e-posta yanlış gitse sorun küçüktür, ama aynı durum kart çekimi veya fiziksel sevkiyat için geçerliyse ciddi sonuçlar doğurur.
Yazı tekrarları üç kaynağa ayırıyor: gönderen tarafın aynı tetikleyiciyi iki kez işlemesi ya da atomik olmayan toplu gönderim, broker'ın at-least-once teslimatı nedeniyle aynı mesajın yeniden gelmesi ve yan etkilerin, örneğin e-postanın, veritabanı işlemi geri alınsa bile geri alınamaması. Çözüm olarak kararlı mesaj kimlikleri, outbox deseni, iş mantığının idempotent yazılması ve yan etkiler için ayrı bir handler öneriliyor.
Gerçek dünyada kullanımı
- Bir HTTP isteğiyle tetiklenen ve mesaj yayımlayan bir ASP.NET Core API'sinde istemci yeniden denediğinde çift sipariş bildirimi göndermemek.
- Amazon SQS gibi at-least-once kuyruktan okuyan bir arka plan worker'ında aynı siparişin iki kez işlenmesini önlemek.
- Ödeme veya e-posta gönderen bir süreçte üçüncü taraf çağrılarını idempotent hale getirmek.
Neden önemli
Kuyruk tabanlı bir sistemde duplicate mesajı bir hata değil beklenen bir durum olarak tasarlamak gerekir. Stabil mesaj kimlikleri, outbox ve idempotent handler'lar birlikte kullanıldığında yinelenen mesajlar veri tutarlılığını bozmaz.