Bir tüketicide bir istisna oluştuğunda, ApsaraMQ for RocketMQ hata kurtarmayı gerçekleştirmek amacıyla mesajı tüketim yeniden deneme ilkesine göre yeniden iletir. Bu konu, tüketim yeniden deneme özelliğinin kullanım senaryolarını, çalışma mekanizmasını, sürüm uyumluluğunu ve kullanım önerilerini açıklar.
Senaryolar
ApsaraMQ for RocketMQ tüketim yeniden denemesi, öncelikle iş mantığındaki hatalardan kaynaklanan mesaj tüketimi eksikliği sorunlarını giderir. Bu özellik, iş süreçleriniz için bir geri dönüş stratejisidir ve iş akışı kontrolü için kullanılmamalıdır.
-
Mesaj yeniden denemesini aşağıdaki senaryolarda kullanın:
İş mantığı başarısız olur ve bu başarısızlık mevcut mesaj içeriğiyle ilişkilidir; örneğin, bu mesaja ait işlem çözümü henüz alınamamıştır ancak kısa bir gecikme sonrası başarı beklenmektedir.
Tüketim hatasının nedeni sistematik değildir; yani mevcut mesaj tutarlı bir arıza yerine nadir görülen bir olay nedeniyle başarısız olmuştur ve sonraki mesajların başarılı olması muhtemeldir. Bu durumda mevcut mesajı yeniden denemek sürecin engellenmesini önler.
-
Aşağıdaki senaryolarda mesaj yeniden denemesinden kaçının:
Tüketim hatasını işleme mantığında koşullu bir dal olarak kullanmak mantıksızdır çünkü mantık zaten bu dalın sık sık gerçekleşeceğini öngörmektedir.
Hız sınırlaması (rate limiting) uygulamak için tüketim hatasını kullanmak uygun değildir. Hız sınırlaması, aşırı trafiği geçici olarak kuyruğa alarak tepe yükünü azaltmayı amaçlar; mesajları yeniden deneme yoluna yönlendirmeyi değil.
Amaç
Asenkron gevşek bağlama (decoupling) için mesaj odaklı ara katman yazılımı kullanıldığında, alt hizmetlerin mesajları işleyemediği durumlarda çağrı zincirinin bütünlüğünün nasıl sağlanacağı aşılması gereken bir zorluktur. Finansal düzeyde güvenilir bir iş mesajı odaklı ara katman yazılımı olan ApsaraMQ for RocketMQ, mesaj teslimat işleme mekanizmasında doğal olarak güvenilir bir iletim stratejisini destekleyecek şekilde tasarlanmıştır. Eksiksiz onay ve yeniden deneme mekanizmaları sayesinde her mesajın iş beklentilerine uygun olarak işlenmesi sağlanır.
ApsaraMQ for RocketMQ mesaj onay mekanizmasını ve tüketim yeniden deneme ilkelerini anlamak, aşağıdaki sorunları analiz etmenize yardımcı olabilir:
Mesaj işlemenin eksiksizliğinin nasıl garanti edileceği: Yeniden deneme ilkesini bilmek, her mesajın tamamen işlendiğini sağlayan, göz ardı edilen mesajları ve tutarsız iş durumlarını önleyen tüketici mantığı tasarlamanıza yardımcı olur.
Sistem arızaları sırasında mesaj durumunun nasıl kurtarılacağı: Bu, sistem anormallikleri (örneğin çökme) sırasında devam eden mesaj durumlarının nasıl geri yüklendiğini ve durum tutarsızlığı olup olmayacağını netleştirir.
Tüketim Yeniden Deneme İlkesi
Tüketim yeniden deneme ilkesi, bir tüketicinin bir mesajı işleyemediği durumdaki yeniden deneme aralığını ve maksimum yeniden deneme sayısını tanımlar.
Yeniden Deneme Tetikleyicileri
Tüketim hatası; buna bir başarısızlık durumu döndürmek veya beklenmeyen bir istisna fırlatmak dahildir.
Mesaj işleme zaman aşımı; buna PushConsumer'deki kuyruk zaman aşımı dahildir.
Ana Yeniden Deneme Davranışları
Yeniden deneme durum makinesi: Yeniden deneme sırasında mesaj durumlarını ve geçişlerini kontrol eder.
Yeniden deneme aralığı: Bir tüketim hatasından (veya zaman aşımından) mesajın yeniden tüketilmeye hazır hale gelmesine kadar geçen süredir.
Maksimum yeniden deneme sayısı: Bir mesajın yeniden denenebileceği en fazla sayıdır.
Mesaj yeniden deneme ilkesi farkları
Yeniden deneme mekanizmaları ve yapılandırma yöntemleri tüketici türüne göre aşağıda gösterildiği gibi farklılık gösterir:
|
Tüketici türü |
Yeniden deneme durum makinesi |
Yeniden deneme aralığı |
Maksimum yeniden deneme sayısı |
|
PushConsumer |
|
Tüketici grubu oluşturulurken meta veriler tarafından kontrol edilir.
|
Konsol veya OpenAPI aracılığıyla ayarlayın |
|
SimpleConsumer |
|
API aracılığıyla mesajları getirirken görünmezlik süresini ayarlayın. |
Konsol veya OpenAPI aracılığıyla ayarlayın |
Ayrıntılı yeniden deneme ilkeleri için bkz. PushConsumer tüketim yeniden deneme ilkesi ve SimpleConsumer tüketim yeniden deneme ilkesi.
PushConsumer Tüketim Yeniden Deneme İlkesi
Yeniden Deneme Durum Makinesi
PushConsumer mesajları işlerken mesajlar aşağıdaki durumlar arasında geçiş yapar:
-
Ready: Hazır durumu.
Mesaj, ApsaraMQ for RocketMQ sunucusunda hazırdır ve tüketiciler tarafından tüketilebilir.
-
Inflight: İşleme durumu.
Inflight: Mesaj tüketici istemcisi tarafından alınmış ve işlenmektedir ancak henüz bir tüketim sonucu döndürmemiştir.
-
WaitingRetry: Bekleyen yeniden deneme durumu; yalnızca push tüketicilere özgü bir durumdur.
WaitingRetry: Mesaj işleme başarısız olduğunda veya zaman aşımına uğradığında tetiklenen PushConsumer'e özel bir durumdur. Mevcut yeniden deneme sayısı maksimuma ulaşmamışsa mesaj WaitingRetry durumuna girer. Yeniden deneme aralığından sonra yeniden tüketilmek üzere Ready durumuna döner. Kalıcı hatalarda yüksek frekanslı yeniden denemeleri önlemek için yeniden deneme aralıkları denemeler ilerledikçe artar.
-
Commit: Onay durumu.
Commit: Başarılı tüketimi gösterir. Tüketici bir başarı yanıtı döndürdüğünde mesaj durum makinesi sonlanır.
-
DLQ: Ölü mektup kuyruğu.
DLQ: Ölü mektup durumu — son geri dönüş seçeneği. Yeniden denemeler maksimum sayıyı aşar ve ölü mektup mesajı saklama etkinleştirilirse başarısız mesaj bir ölü mektup konusuna gönderilir. İş operasyonlarını geri yüklemek için bu konudaki mesajları tüketebilirsiniz. Ayrıntılar için bkz. Ölü mektup mesajları.
-
Discard: At.
Discard: Yeniden denemeler maksimum sayıyı aşar ve ölü mektup saklama devre dışı bırakılırsa mesaj atılır.

Örnek: Yukarıdaki diyagramda bir mesajın Ready durumunda 5 saniye kaldığını ve işlenmesinin 6 saniye sürdüğünü varsayalım.
Her yeniden deneme döngüsü Ready → Inflight → WaitingRetry sırasını izler. Yeniden deneme aralığı, bir başarısızlıktan (veya zaman aşımından) mesajın tekrar Ready durumuna gelmesine kadar geçen süredir. İki tüketim girişimi arasındaki gerçek süre ayrıca işleme süresini ve Ready süresini de içerir. Örneğin:
saniyede mesaj Ready durumuna girer.
Tüketici işleme hızı nedeniyle tüketim 5. saniyede başlar. 6 saniye sonra (11. saniyede) bir istisna oluşur ve istemci başarısızlık döndürür.
Yeniden deneme hemen başlayamaz; yeniden deneme aralığının beklenmesi gerekir.
saniyede mesaj tekrar Ready durumuna gelir.
İstemci 5 saniye sonra yeniden tüketmeye başlar.
Böylece iki tüketim girişimi arasındaki gerçek aralık şudur: işleme süresi + yeniden deneme aralığı + Ready süresi = 21 sn.
Yeniden Deneme Aralıkları
-
Sırasız mesajlar (non-ordered messages): Yeniden deneme aralığı aşağıda gösterildiği gibi adımlı zaman yaklaşımını kullanır:
Yeniden deneme denemesi
Yeniden deneme aralığı
Yeniden deneme denemesi
Yeniden deneme aralığı
1
10 saniye
9
7 dakika
2
30 saniye
10
8 dakika
3
1 dakika
11
9 dakika
4
2 dakika
12
10 dakika
5
3 dakika
13
20 dakika
6
4 dakika
14
30 dakika
7
5 dakika
15
1 saat
8
6 dakika
16
2 saatNotYeniden deneme denemeleri 16'yı aşarsa sonraki tüm yeniden denemeler 2 saatlik bir aralık kullanır.
Sıralı mesajlar: Sabit bir yeniden deneme aralığı kullanın. Belirli değerler için bkz. Parametre sınırları.
Maksimum Yeniden Deneme Sayısı
Varsayılan değer: 16.
Maksimum: 1.000.
PushConsumer için maksimum yeniden deneme sayısı tüketici grubu meta verileri tarafından kontrol edilir. Değiştirmek için bkz. Maksimum yeniden deneme sayısını değiştirin.
Örneğin maksimum yeniden deneme sayısı 3 ise mesaj en fazla 4 kez iletilir: bir kez orijinal olarak ve üç kez yeniden deneme yoluyla.
Kullanım Örneği
PushConsumer'da yeniden denemeyi tetiklemek için basitçe bir tüketim başarısızlığı durum kodu döndürün. Beklenmeyen istisnalar SDK tarafından otomatik olarak yakalanır.
SimpleConsumer simpleConsumer = null;
// Consumption example: Use PushConsumer to consume normal messages. Return an error on failure to trigger retry.
MessageListener messageListener = new MessageListener() {
@Override
public ConsumeResult consume(MessageView messageView) {
System.out.println(messageView);
// Return FAILURE to trigger automatic retry until the maximum retry count is reached.
return ConsumeResult.FAILURE;
}
};
Tüketim Yeniden Deneme Günlüklerini Görüntüleyin
Sıralı mesajlar için PushConsumer yeniden denemeleri istemci tarafında gerçekleştirir. Sunucu ayrıntılı yeniden deneme günlüklerine erişemez. Mesaj izleme sıralı bir mesaj için teslimat başarısızlığını gösteriyorsa maksimum yeniden deneme sayısı ve istemci bilgileri için tüketici istemci günlüklerini kontrol edin.
İstemci günlük yolunu görmek için bkz. Günlük yapılandırması.
Tüketim hatası ayrıntılarını hızlıca bulmak için istemci günlüklerinde şu anahtar sözcükleri arayın:
Message listener raised an exception while consuming messages
Failed to consume fifo message finally, run out of attempt times
SimpleConsumer Tüketim Yeniden Deneme İlkesi
Yeniden Deneme Durum Makinesi
SimpleConsumer mesajları işlerken mesajlar aşağıdaki durumlar arasında geçiş yapar:
-
Ready: Hazır durumu.
Mesaj, ApsaraMQ for RocketMQ sunucusunda hazırdır ve tüketiciler tarafından tüketilebilir.
-
Inflight: İşleme durumu.
Inflight: Mesaj tüketici istemcisi tarafından alınmış ve işlenmektedir ancak henüz bir tüketim sonucu döndürmemiştir.
-
Commit: Onay durumu.
Commit: Başarılı tüketimi gösterir. Tüketici bir başarı yanıtı döndürdüğünde mesaj durum makinesi sonlanır.
-
DLQ: Ölü mektup kuyruğu.
DLQ: Ölü mektup durumu — son geri dönüş seçeneği. Yeniden denemeler maksimum sayıyı aşar ve ölü mektup mesajı saklama etkinleştirilirse başarısız mesaj bir ölü mektup konusuna gönderilir. İş operasyonlarını geri yüklemek için bu konudaki mesajları tüketebilirsiniz. Ayrıntılar için bkz. Ölü mektup mesajları.
-
Discard: At.
Discard: Yeniden denemeler maksimum sayıyı aşar ve ölü mektup saklama devre dışı bırakılırsa mesaj atılır.
PushConsumer'dan farklı olarak SimpleConsumer önceden tahsis edilmiş bir yeniden deneme aralığı kullanır. Bir mesajı getirirken tüketici InvisibleDuration parametresini ayarlar; bu, izin verilen maksimum işleme süresidir. Başarısızlık durumunda sonraki yeniden deneme aralığı ek yapılandırmaya gerek kalmadan bu değeri yeniden kullanır.

InvisibleDuration önceden tahsis edildiğinden gerçek işleme süresinden önemli ölçüde farklı olabilir. Bunu API aracılığıyla değiştirebilirsiniz.
Örneğin başlangıçta işleme süresini 20 ms olarak ayarlarsanız ancak gerçek işleme bunu aşarsa erken yeniden denemeleri önlemek için InvisibleDuration süresini uzatın.
InvisibleDuration değerini değiştirmek için şu koşullar karşılanmalıdır:
Mesaj işleme zaman aşımına uğramamış olmalıdır.
Tüketim durumu onaylanmamış olmalıdır.
Aşağıda gösterildiği gibi yeni InvisibleDuration değeri hemen etkili olur — görünmezlik zamanlayıcısını API çağrısı anından itibaren yeniden başlatır.

Yeniden Deneme Aralığı
Yeniden deneme aralığı = InvisibleDuration − Gerçek işleme süresi
SimpleConsumer yeniden deneme aralıklarını InvisibleDuration aracılığıyla kontrol eder. Örneğin InvisibleDuration 30 ms ise ve işleme 10 ms sonra başarısız olursa sonraki yeniden deneme 20 ms sonra gerçekleşir. İşleme 30 ms içinde bitmez ve sonuç döndürülmezse mesaj zaman aşımına uğrar ve hemen yeniden denenir (0 ms aralık).
Maksimum Yeniden Deneme Sayısı
Varsayılan değer: 16.
Maksimum: 1.000.
SimpleConsumer için maksimum yeniden deneme sayısı oluşturma sırasında tüketici grubu meta verileri tarafından kontrol edilir. Değiştirmek için bkz. Maksimum yeniden deneme sayısını değiştirin.
Örneğin maksimum yeniden deneme sayısı 3 ise mesaj en fazla 4 kez iletilir: bir kez orijinal olarak ve üç kez yeniden deneme yoluyla.
Kullanım Örneği
SimpleConsumer'da yeniden denemeyi tetiklemek için sadece bekleyin.
// Consumption example: Use SimpleConsumer to consume normal messages. To trigger retry, remain silent and let the message time out. The server will automatically retry.
List<MessageView> messageViewList = null;
try {
messageViewList = simpleConsumer.receive(10, Duration.ofSeconds(30));
messageViewList.forEach(messageView -> {
System.out.println(messageView);
// On failure, ignore the message. It will become visible again and be retried.
});
} catch (ClientException e) {
// If pull fails due to throttling or other system issues, retry the receive request.
e.printStackTrace();
}
Maksimum Yeniden Deneme Sayısını Değiştirin
PushConsumer ve SimpleConsumer için maksimum yeniden deneme sayısını değiştirmek amacıyla aşağıdaki yöntemleri kullanın.
1. İstemciniz Remoting protokolünü kullanıyorsa gerçek maksimum yeniden deneme sayısı istemci tarafındaki ayarı takip eder ve bu yapılandırmanın etkisi yoktur. İstemciniz gRPC kullanıyorsa buradaki ayar uygulanır.
2. Yeniden deneme stratejileri (üstel geri çekilme veya sabit aralık) yalnızca gRPC istemcileri için geçerlidir ve Remoting istemcileri üzerinde etkisi yoktur.
gRPC SDK
OpenAPI aracılığıyla değiştirin: Tüketici grubunu güncelleyin
-
Konsol aracılığıyla değiştirin:
Ayara erişmek için:
Instances sayfasında hedef örnek adına tıklayın.
Soldaki gezinme bölmesinde Groups öğesine tıklayın. Groups sayfasında Create Group öğesine tıklayın.
Create Group iletişim kutusunda Group ID (1–60 karakter), Delivery Order (Concurrent Delivery veya Ordered Delivery) ve Description değerlerini ayarlayın. Gelişmiş Ayarlar'ı genişleterek yeniden deneme ilkesini Exponential Backoff olarak yapılandırın, Maximum Retry Count değerini ayarlayın (varsayılan: 16) ve Retain Dead-letter Messages seçeneğini açın/kapatın (varsayılan: kapalı; kapalıysa yeniden deneme sayısını aşan mesajlar atılır).
Remoting SDK
Remoting SDK parametresi aracılığıyla değiştirin: Tüketicinin maxReconsumeTimes özelliğini ayarlayın.
En İyi Uygulamalar
Makul Şekilde Yeniden Deneyin — Hız Sınırlaması İçin Yeniden Denemeyi Kullanmayın
Senaryolar bölümünde belirtildiği gibi mesaj yeniden denemesi nadir görülen iş başarısızlıkları için uygundur; hız sınırlaması gibi sistematik veya sürekli başarısızlıklar için değil.
-
Yanlış örnek:
Tüketim hızı hız sınırlamasını tetiklerse başarısızlık döndürün ve yeniden denemeyi bekleyin.
-
Doğru örnek:
Tüketim hızı hız sınırlamasını tetiklerse mesaj getirmeyi geciktirin ve daha sonra tüketin.
Mesaj Yeniden Denemesi Hakkında Sıkça Sorulan Sorular
Mesaj Tüketimi Zaman Aşımı Nasıl Ayarlanır?
gRPC Protocol
-
SimpleConsumer: Zaman aşımı aralığı 10 saniye ile 12 saat arasındadır.
Kod örneği:
private long minInvisiableTimeMillsForRecv = Duration.ofSeconds(10).toMillis(); private long maxInvisiableTimeMills = Duration.ofHours(12).toMillis(); PushConsumer: Varsayılan 230 dakikadır ve değiştirilemez.
Remoting Protocol
consumer.setConsumeTimeout(15); // Unit: minutes. Range: 1–180 minutes