Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
İleti tüketicilerini, aynı iletinin birden çok kez işlenmesinin, iletinin bir kez işlenmesiyle aynı etkiye sahip olması için tasarlayın. En az bir kez teslim garantisi veren mesajlaşma sistemleri aynı iletiyi birden çok kez teslim edebilir. Yinelemelere karşı dayanıklılık olmadan, bir iletiyi yeniden işlemek yinelenen kayıtlar oluşturabilir, bir müşteriyi iki kez ücretlendirebilir veya diğer istenmeyen etkilere neden olabilir.
Bağlam ve sorun
Dağıtılmış uygulamalar, işleri doğrudan eşzamanlı çağrılar yerine genellikle bir mesaj aracısı üzerinden iletir. Azure Service Bus, Azure Event Hubs, Apache Kafka ve RabbitMQ gibi çoğu aracı en az bir kez teslim sağlar. Bu garanti, hata oluştuğunda bile iletinin bir tüketiciye ulaşmasını sağlar, ancak aynı zamanda aracının aynı iletiyi birden çok kez teslimebileceği anlamına da gelir.
Yinelenenler birkaç farklı kaynaktan ortaya çıkabilir:
Üretici yeniden denemeleri
Üretici bir ileti gönderir, geçici bir ağ hatası veya zaman aşımı nedeniyle bildirim almaz ve iletiyi yeniden gönderir. Gönderim ilk seferde başarılı olmuş olsa da aracı artık iki kopya tutuyor.
Eksik bir bildirimden sonra yeniden teslim
Tüketici bir iletiyi alır ve işler, ancak tüketici kilitlendiğinden, kilidin süresi dolduğundan veya bildirim kaybolduğundan bunu onaylayamaz. Broker, iletinin işlenmediğini varsayar ve onu yeniden teslim eder.
İşlem sırasında oluşan tüketici hataları
Tüketici, bir veritabanı yazma işlemini tamamlar ancak iletiyi kabul etmeden önce kilitlenir. Başka bir örnek yeniden teslim edilen iletiyi aldığında, yazma işlemini yineler.
Bir iletinin yalnızca bir kez teslim edilmesini dağıtılmış bir sistem genelinde garanti etmek pratik değildir. Tam olarak bir kez işleme semantiği sunduğunu iddia eden aracılar bile yalnızca doğrudan kendilerinin denetlediği işlemleri garanti eder; örneğin mesajları tüketicilere teslim etmeyi veya verileri yeniden aracıya yazmayı. Tüketicilerin diğer sistemlerde gerçekleştirdikleri dış yan etkileri garantileyemezler. Dayanıklı çözüm, yinelenen teslimi ortadan kaldırmak değildir. Tüketicinin buna tolerans göstermesini sağlamak için. En az bir kez teslim ile yinelenenleri göz ardı eden bir tüketiciyi birleştirdiğinizde, fiilen tam olarak bir kez işleme elde edersiniz.
Solution
İşlenen iletilerin kaydını tutarak ve daha önce gördüğü tüm iletileri atlayarak tüketiciyi idempotent hâle getirin. Tüketici, bu kararı yeniden teslim durumunda da geçerliliğini koruyan kararlı bir tanımlayıcıya göre verir, bu tanımlayıcının daha önce işlenip işlenmediğini belirlemek için kalıcı depoyu kontrol eder ve ardından ya mesajı işler ya da yinelenen olduğunu belirleyip yok sayar.
Aşağıdaki adımlarda çekirdek akış açıklanmaktadır:
- İletiyi okuyun ve tekilleştirme anahtarını çıkarın.
- O anahtar için tekilleştirme deposuna bakın.
- Anahtar varsa, iletiyi yinelenen olarak değerlendirin. Bunu onaylayın ve isteğe bağlı olarak daha önce kaydedilen sonucu döndürerek durdurun.
- Anahtar yoksa, iletiyi işleyin ve anahtarı tek bir atomik işlemde kaydedin, ardından iletiyi onaylayın.
Sabit bir tekilleştirme anahtarı seçin
Anahtarın her yeniden teslimde mantıksal iletiyi benzersiz ve tutarlı bir şekilde tanımlaması gerekir. Üretici tarafından atanan bir ileti tanımlayıcısı veya birkaç iletinin taşıyabileceği paylaşılan bağıntı bağlamını değil, belirli bir mantıksal işlemi tanımlayan iş düzeyinde bir idempotency anahtarı kullanın. Azure Service Bus özelliği, MessageId iletiyi ve yükünü benzersiz olarak tanımladığından bu amaca hizmet eder. anahtar olarak kullanmayın CorrelationId çünkü istek ve yanıtları gibi ilgili iletileri gruplandırır. CloudEvents belirtimini izleyen olaylar için, id ve source özniteliklerinin birleşimi bir olayı benzersiz olarak tanımlar ve yeniden teslimatlar arasında değişmeden kalır.
Aracının yeniden teslim sırasında yeniden oluşturduğu taşıma düzeyi tanımlayıcıları ile teslim denemelerinden türetilen değerlere dayanmayın; çünkü bu değerler yinelenen iletiler arasında değişir ve tespiti engeller. Ayrıca anahtarı alma zaman damgaları gibi geçici alanlardan türetmekten kaçının.
Yayımlama-abone olma tasarımında birden çok abone gibi birden fazla bağımsız tüketici aynı kanalı işlediğinde, her tüketici kendi ileti kopyasını meşru bir şekilde işler ve ileti işlemenin tamamlanmasını bağımsız olarak izlemesi gerekir. Bu tüketiciler tek bir yineleme kaldırma deposunu paylaşıyorsa, kaydı tüketici kimliği ile ileti kimliğinin birleşimine göre anahtarlayın. Yalnızca ileti kimliğine göre anahtarlanan bir veri deposu, ilk tüketicinin diğer tüm tüketiciler için işlemeyi engellemesine olanak tanır.
İşlenen anahtarların nerede depolandığına karar verme
İki yaygın seçeneğiniz vardır:
Özel bir tekilleştirme tablosu. Tüketici, işlenen anahtar başına bir satır tutan, bazen gelen kutusu olarak da adlandırılan ayrı bir tablo tutar. Bu yaklaşım, tekilleştirme ile ilgili hususları iş verisinden ayrı tutar ve birçok ileti türü aynı mekanizmayı paylaştığında iyi çalışır.
Ticari tüzel kişiliğin kendisi. Tüketici, anahtarı iletinin oluşturduğu veya güncellediği kayıtta depolar. Bu yaklaşım ayrı bir tablo kullanımını önler, ancak tekilleştirmeyi iş verisinin yapısına bağlar.
İşaretçiyi ve yan efektleri atomik olarak işleme
Denetim ve işlem akışında bir hata penceresi vardır. Tüketici iletiyi işler ve ardından anahtarı ayrı bir adımda kaydederse, bu iki işlem arasında meydana gelen bir çökme, yan etkilerin uygulanmış olmasına karşın anahtarın kaydedilmemiş olmasına neden olur; böylece ileti bir sonraki teslimatta yeniden işlenir.
Yinelenenleri kaldırma işaretçisini ve aynı işlemdeki iş yan etkilerini yazarak bu hata penceresini giderin. Her ikisi de ya birlikte kalıcı olarak kaydedildiğinde ya da hiç kaydedilmediğinde, yeniden teslimat ya kaydedilmiş işaretçiyi bulup atlar ya da işlem geri alındığı için hiçbir işaretçi bulmaz ve güvenle yeniden işler. Bu işlemsel varyant, gelen kutusu desenidir ve üretici tarafındaki İşlemsel Giden Kutusu deseninin tüketici tarafındaki karşılığıdır.
Eşzamanlı yinelemelere karşı koruma
Birden çok yarışan tüketicinin bulunduğu en az bir kez teslimat modelinde, iki uygulama örneği aynı iletinin kopyalarını aynı anda alabilir. Her ikisi de, taraflardan biri commit etmeden önce varlık kontrolünden geçebilir; bu nedenle yalnızca bu kontrol, aynı işlemin iki kez gerçekleştirilmesini önlemez.
Uygulama mantığı yerine veri deposunda doğruluğu zorunlu kılma:
Yinelenenleri kaldırma anahtarında benzersiz bir kısıtlama kullanın. Her iki işlem de anahtarı eklemeyi dener, ancak yalnızca biri başarılı olur. Diğeri kısıtı karşılamaz ve iletiyi yinelenmiş olarak değerlendirir. Bu yaklaşım veritabanını yarışın tek arbiter'i yapar.
Önbelleklerde önce kontrol sonra ayarlanmış yarışlardan kaçının. Bir anahtarı önce denetleyip ardından iki ayrı işlemde ayarlayan bir desen, eşzamanlı yeniden denemelerin her ikisinin de anahtarı sahiplenmesine olanak tanıyan bir zaman aralığı bırakır. Anahtarın sahiplenilmesi tek bir atomik adım olsun diye, çakışma durumunda başarısız olan ekleme ya da yoksa değer atama işlemi gibi atomik bir koşullu yazma işlemi kullanın.
İşleme katılamayan yan etkileri işleyin
Üçüncü taraf API çağırma veya bir dış depoya yazma gibi bazı işlemler tüketicinin veritabanı işlemine katılamaz. Bu işlemler için iki aşamalı bir yaklaşım kullanın:
- Dış eylemi gerçekleştirmeden önce anahtarı devam ediyor durumunda kaydedin.
- İşlemi gerçekleştirin.
- Kaydı tamamlandı olarak güncelleştirin ve sonucu depolayın.
Yeniden teslimatta, tamamlanmış bir kayıt çağrıyı tekrarlamanızı önler. Devam eden kayıt, önceki bir denemenin kısmen tamamlandığını veya başka bir tüketici tarafından üzerinde çalışıldığını gösterir.
Sorunlar ve dikkat edilmesi gerekenler
Bu düzenin nasıl uygulaneceğine karar velarken aşağıdaki noktaları göz önünde bulundurun:
Doğal olarak etkili işlemleri tercih edin. Bazı işlemler doğası gereği idempotenttir ve tekilleştirme için ek takip gerektirmez. İş tanımlayıcısına göre anahtarlanmış bir upsert işlemi, bir artırma yerine mutlak bir değer ayarlayan bir yazma işlemi veya bir kaynak tanımlayıcısına yapılan bir HTTP
PUTisteği, bir kez ya da birçok kez çalıştırılsa da aynı sonucu üretir.Bazen bir işlemi, iletinin siparişin yeni durumu gibi ortaya çıkan mutlak durumu taşıdığı olayla taşınan durum aktarımı sayesinde doğal olarak idempotent hâle getirebilirsiniz; böylece tüketici bunu göreli bir değişiklik yerine bir upsert olarak uygular.
Tip
Önce doğal idempotentlik için tasarım yapın ve yalnızca doğal olarak idempotent hâle getirilemeyen işlemler için tekilleştirme teknikleri ekleyin.
Tekilleştirme kayıtlarının yaşam döngüsünü yönetin. Yineleme giderme kayıtları, sürelerini sonlandırmadığınız sürece birikir. Aracı özgün iletiyi yeniden teslimabildiği sürece her kaydı koruyun. Bu pencere, ileti aracısının maksimum teslim denemelerine, kilit veya görünürlük zaman aşımına ve iletinin yaşam süresine bağlıdır. Gecikmiş bir yeniden teslimatın işaretçisini hâlâ bulabilmesi için, tekilleştirme kayıtları için bu aralığı aşan bir yaşam süresi ayarlayın. Kayıtların çok erken silinmesi, pencereyi yinelemeler için yeniden açar. Bir yeniden gönderim, normal yeniden teslim süresinden çok sonra gerçekleşebileceğinden, bir operatörün ölü harf kuyruğundan yeniden gönderdiği iletileri hesaba katın.
Tekilleştirmeyi elle geliştirmek yerine bir mesajlaşma çerçevesi kullanın. Tekilleştirme deposunun, atomik kesinleştirmenin ve kayıtların temizlenmesinin doğru şekilde uygulanması hataya açıktır. İleti tabanlı çerçeveler bu düzeni yerleşik bir özellik olarak sağlar.
Örneğin, NServiceBus gelen iletileri ileti tanımlayıcılarına göre tekilleştirir ve tekilleştirme verileri için yapılandırılabilir saklama ve temizleme olanağı sağlar. MassTransit tüketici gelen kutusu, alınan iletileri ileti tanımlayıcılarına göre takip ederek tüketicinin her iletiyi tam olarak bir kez işlemesini sağlar.
Broker tekilleştirmesi, idempotent tüketici mantığına duyulan ihtiyacı azaltır ancak ortadan kaldırmaz. Bazı platformlar, aktarım katmanında yinelenenleri filtreler. Azure Service Bus’taki yinelenen algılama, yapılandırılmış bir zaman aralığında yinelenen bir
MessageIdtaşıyan iletileri siler; bu da üreticinin gönderme yeniden denemelerinden kaynaklanan yinelenen iletileri önler. Bu özellik, gönderme tarafında ve sınırlanmış bir pencerede çalışır. Bir tüketicinin yeniden teslimden sonra aynı iletiyi iki kez işlemesini engellemez, bu nedenle yine de aynı anda etkili bir tüketici mantığına ihtiyacınız vardır. Platform özelliklerini, desenin yerine geçen bir unsur olarak değil, yinelenen miktarı azaltan ilk savunma katmanı olarak değerlendirin.İleti sıralama hesabı. Tekilleştirme, yinelenenleri kaldırır ancak sırayı garanti etmez. Tüketici işleme sırasına bağımlıysa, bu düzeni Azure Service Bus ileti oturumları gibi bir sıralama mekanizmasıyla birleştirin veya tüketicinin eski iletileri reddetmesine izin veren sıra veya sürüm verilerini ekleyin.
Gözlemlenebilirlik için bir araç. Tekilleştirme anahtarını ve korelasyon kimliğini yapılandırılmış günlüklerde yayınlayın ve algılanan yinelenenler için bir metriği izleyin. Yükselen bir yinelenme oranı, üretici yapılandırma hatasına, yetersiz bir onay ya da kilit penceresine veya sağlıklı çalışmayan tüketicilere işaret edebilir. Hizmetler arasında bir iletiyi izlemek için uçtan uca izlemeyi ve bağıntıyı kullanın.
Aşağı akış çağrılarına idempotency yayma. Bir consumer’ı idempotent hâle getirmek, çağırdığı servisleri korumaz. Bir tüketici, işleme kapsamında alt hizmetleri çağırdığında, her katmanın kendi işlemlerindeki yinelemeleri kaldırabilmesi için idempotency anahtarını iletin.
Bu desen ne zaman kullanılır?
Bu düzeni aşağıdaki durumlarda kullanın:
Çoğu aracıda varsayılan olan en az bir kez teslimat sağlayan bir aracıdan iletiler tüketirsiniz.
İletinin yeniden işlenmesi yinelenen finansal işlemler, yinelenen kaynak oluşturma veya yinelenen bildirimler gibi yanlış sonuçlar üretir.
Birden çok rakip tüketici aynı kanalı işler ve bu da eşzamanlı yinelenen teslimi olası hale getirir.
Bu düzen aşağıdaki durumlarda uygun olmayabilir:
Tüketicinin yaptığı her işlem zaten doğal olarak idempotent olduğundan, yeniden işlemek zararsızdır ve tekilleştirme için kayıt tutmak bir fayda sağlamadan ek maliyet yaratır.
İş yükü, zaman zaman yinelenen işlemlerin etkilerini tolere edebilir ve yinelenenleri kaldırma deposunun maliyeti, yinelemenin etkisinden daha ağır basar.
Mesajlaşmanın ötesinde etkili işleme
Bu model, mesaj tüketicilerine idempotentlik kazandırır, ancak idempotent işleme daha kapsamlı bir güvenilirlik ilkesidir. Aynı görev üzerinde birden çok kez çalıştırabilen tüm işlemler bundan yararlanır. Bu ilke, tekrar oynatılan verileri yeniden işleyen ayıklama, dönüştürme ve yükleme (ETL) dönüşümlerini, bir denetim noktasından sürdürülen akış işlemeyi, çakışan veya yeniden başlatılan zamanlanmış işleri ve yinelenen teslimatlar alan web kancaları veya HTTP uç noktalarını içerir.
Her durumda aynı çekirdek teknik geçerlidir:
- Kararlı bir anahtarla çalışma birimini tanımlayın.
- İşlediğiniz işlemi kaydedin.
- Yinelenenleri atlayın veya özümseyin; böylece aynı işlemin tekrarlanması sonucu değiştirmez.
Bu makaledeki kararlı anahtarlar, atomik işaretçiler ve benzersiz kısıtlamalar gibi mekanizmalar, hiçbir ileti aracısı söz konusu olmadığında bile bu bağlamlara aktarılır.
İş yükü tasarımı
Azure Well-Architected Framework sütunlarında ele alınan hedef ve ilkeleri karşılamak için, bir iş yükü tasarımında Idempotent Consumer deseninin nasıl kullanılacağını değerlendirin. Aşağıdaki tabloda, bu desenin her bir sütunun hedeflerini nasıl desteklediği hakkında rehberlik sağlanmaktadır.
| Temel | Bu desen sütun hedeflerini nasıl destekler? |
|---|---|
| Güvenilirlik tasarımı kararları, iş yükünüzün hatalı çalışmaya dayanıklı olmasına ve bir hata oluştuktan sonra tamamen çalışır duruma geldiğinden emin olmasına yardımcı olur. | Bu düzen, bir iş yükünün verileri bozmadan en az bir kez teslim ve güvenli yeniden denemeler kullanmasını sağlar ve bu da yinelenen teslimi bir doğruluk riskinden tolere edilmiş bir koşula dönüştürür. - RE:07 Kendini koruma - Geçici hataları işleme |
Bu model bir sütun içinde dengeleri ortaya çıkartıyorsa, bunları diğer sütunların hedeflerine karşı değerlendirin.
Example
Aşağıdaki örnek, Azure Service Bus’tan gelen siparişleri işleyen ve durumu NoSQL için Azure Cosmos DB’de kalıcı olarak depolayan idempotent bir tüketiciyi göstermektedir.
Üretici, Service Bus MessageId iş düzeyinde bir sipariş tanımlayıcısına ayarlar. Tüketici PeekLock modunda iletiler alır ve bu, tüketici bunu kilit süresi içinde tamamlamazsa iletiyi yeniden teslim eder. Tüketicinin Azure Cosmos DB kapsayıcısı, sipariş tanımlayıcısı (/orderId) üzerinde bölümler oluşturur ve belgeyi id aynı sipariş tanımlayıcısına ayarlar, böylece belirli bir siparişin her kopyası aynı mantıksal bölüme çözümlenip sipariş kaydının kendisi yinelenenleri kaldırma işaretçisi görevi görür.
Tüketici her iletiyi aşağıdaki gibi işler:
- İletiyi okuyun ve
MessageIdöğesini tekilleştirme anahtarı olarak kullanın. - Sipariş belgesini,
idve bölüm anahtarı her ikisi de sipariş tanımlayıcısına ayarlanmış olarak oluşturun. - Oluşturma işlemi başarılı olursa, Service Bus’ın iletiyi kuyruktan kaldırması için iletiyi tamamlayın.
- Oluşturma işlemi, bu
iddeğerine sahip bir belge zaten mevcut olduğundan HTTP 409 (Çakışma) durumu nedeniyle başarısız olursa, mevcut belgeyi okuyun ve bunu geçerli iletiyle karşılaştırın. Depolanan bir istek özeti veya değiştirilemez iş alanları eşleşiyorsa, mesajı yinelenen bir mesaj olarak değerlendirin, tamamlayın ve işlemeyi atlayın. Bunlar eşleşmiyorsa, üretici farklı içerik için tanımlayıcıyı yeniden kullanmış olabilir veya sipariş ayrıntıları ilk işlenmeden bu yana değişmiş olabilir, bu nedenle iletiyi sessizce atmak yerine iletinin yanıt vermemesi veya uyarı oluşturması. - İşleme geçici bir nedenden dolayı başarısız olursa, Service Bus yeniden teslim edebilmesi için iletiyi bırakın veya başka bir tüketicinin alması için kilidin süresinin dolmasına izin verin.
Oluşturma işlemi atomiktir, bu nedenle hem yinelenenleri kaldırma denetimi hem de yazma görevi görür. Aynı iletinin kopyalarını alan iki tüketici siparişi oluşturamaz. Biri oluşturur kazanır, diğeri bir çakışma döndürür ve yinelemesini güvenli bir şekilde atar.
İşleme işleminin birden fazla belge yazması gerektiğinde, aynı bölüm anahtarı içinde hem tekilleştirme belgesini hem de iş belgelerini içeren bir işlemsel toplu işlem kullanın. Bir işlemsel toplu işlem tek bir mantıksal bölüm içinde gerçekleştiğinden, tek bir iletiye ait tüm belgelerin ortak olarak kullandığı bir bölüm anahtarı seçin. Toplu işlem, tüm belgeleri tek seferde kaydeder ya da hiçbirini kaydetmez; bu nedenle işleme ile onay arasında meydana gelen bir çökme, mükerrer kayıt işaretçisi ile iş verilerinin senkronizasyonunu bozamaz. Zaten var olan bir belgeyi oluşturmaya çalışan bir toplu işlem, mükerrer kaydı belirten 409 (Çakışma) durum kodunu döndürür.
Bu alıcıyı yinelenen gönderim yeniden denemelerine karşı da dayanıklı hale getirmek için kuyrukta yinelenen algılama özelliğini etkinleştirin. Yinelenenleri algılama, geçmiş aralığı içinde yinelenen gönderimleri engeller ve idempotent tüketici, bu aralığın dışında kalan veya yeniden teslimden kaynaklanan tüm yinelenenleri işler.
Sonraki adım
- Azure'daki zaman uyumsuz mesajlaşma seçenekleri, teslim garantilerinizi ve yinelenen işleme gereksinimlerinizi belirleyen mesajlaşma altyapısı seçeneklerini açıklar.
İlgili kaynaklar
İşlemsel Giden Kutusu deseni, bu desenin yayımcı tarafıdır. İletileri iş verileriyle aynı işlemde işleyerek güvenilir bir şekilde yayımlar.
Yeniden deneme deseni, uygulamaların işlemleri yeniden deneyerek geçici hatalarla başa çıkmasını sağlar; bu nedenle, yeniden denemeler yinelenen teslimata yol açabileceğinden, idempotent işleme gerekli hâle gelir.
Dayanıklı Azure Event Hubs ve Azure İşlevleri tasarımı, olay akışları için tekilleştirme teknikleri de dahil olmak üzere, Azure Event Hubs’ın tetiklediği işlevlere bu modeli uygular.
Azure İşlevleri’ın aynı girdi için tasarlanması, yinelenen çağrıları tolere eden idempotent işlevler oluşturmaya yönelik rehberlik sunar.