Bir tüketici bir mesajı işleyemediğinde veya işlem zaman aşımına uğradığında, ApsaraMQ for RocketMQ bir yeniden deneme ilkesine göre mesajı otomatik olarak yeniden iletir. Tüm yeniden deneme girişimleri tükendiğinde, mesaj bir ölü mektup kuyruğuna taşınır. İş süreçlerinizi devam ettirmek için ölü mektup kuyruklarındaki mesajları tüketebilirsiniz.
Kullanım notları
Mesaj kimliği tüm yeniden deneme girişimleri boyunca değişmez.
Tüketim yeniden denemesi yalnızca kümelenmiş tüketim modunda çalışır. Yayın (broadcasting) tüketim modunda, başarısız olan mesajlar yeniden iletilmez; tüketici sonraki mesaja geçer.
Nasıl çalışır
Bir mesaj aşağıdaki durumlar arasında geçiş yapar:
| Durum | Açıklama |
|---|---|
| Ready | Mesaj broker'da sıraya alınmıştır ve tüketime hazırdır. |
| Inflight | Bir tüketici mesajı çekmiş ve işlemektedir. Henüz bir sonuç döndürülmemiştir. |
| WaitingRetry | Tüketim başarısız oldu veya zaman aşımına uğradı. Mesaj, Ready durumuna geri dönmeden önce yeniden deneme aralığının dolmasını bekler. |
| Commit | Tüketici başarılı bir yanıt döndürdü. Tüketim tamamlandı. |
| DLQ | Ölü mektup mesajlarını saklama özelliği etkinleştirilmişse, tüm yeniden deneme girişimleri tükendikten sonra mesaj ölü mektup konusuna taşınır. |

Yeniden deneme zamanlaması
Arka arkaya gelen iki tüketim girişimi arasındaki aralık üç bileşenden oluşur:
Girişimler arası aralık = tüketim süresi + yeniden deneme aralığı + Ready durumunda geçen süre

Örneğin, bir mesajın Ready durumunda 5 saniye beklediğini ve başarısız olmadan önce işlenmesinin 6 saniye sürdüğünü varsayalım. 10 saniyelik bir yeniden deneme aralığı ile:
0 sn -- Mesaj Ready durumuna girer.
5 sn -- Tüketici mesajı çeker (Inflight).
11 sn -- 6 saniye sonra tüketim başarısız olur. Mesaj WaitingRetry durumuna girer.
21 sn -- 10 saniyelik yeniden deneme aralığından sonra mesaj Ready durumuna döner.
26 sn -- Tüketici, sonraki girişim için mesajı tekrar çeker.
Toplam aralık: 6 + 10 + 5 = 21 saniye.
TCP için yeniden deneme ilkeleri
Sıralı mesajlar
| Ayar | Ayrıntılar |
|---|---|
| Yeniden deneme aralığı | suspendTimeMillis parametresi ile ayarlanır. Geçerli aralık: 10 - 30.000 ms. Varsayılan: 1.000 ms (1 saniye). |
| Maksimum yeniden deneme | MaxReconsumeTimes parametresi ile ayarlanır. Üst sınır yoktur. Varsayılan: Integer.MAX. |
Sırasız mesajlar
| Ayar | Ayrıntılar |
|---|---|
| Yeniden deneme aralığı | Önceden tanımlanmış artan bir zamanlamayı takip eder (aşağıdaki tabloya bakın). Sırasız mesajlar için özel aralıklar desteklenmez. |
| Maksimum yeniden deneme | MaxReconsumeTimes parametresi ile ayarlanır. Üst sınır yoktur. Varsayılan: 16. |
MaxReconsumeTimes değeri 16'yı aşarsa, önceden tanımlanmış zamanlama ilk 16 yeniden deneme için uygulanır. Sonraki tüm yeniden denemeler sabit 2 saatlik bir aralık kullanır.
Sırasız mesajlar için yeniden deneme aralığı zamanlaması
| Yeniden Deneme | Aralık | Yeniden Deneme | Aralık |
|---|---|---|---|
| 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 saat |
HTTP için yeniden deneme ilkeleri
HTTP yeniden deneme ilkeleri önceden tanımlanmıştır ve değiştirilemez.
| Mesaj türü | Yeniden deneme aralığı | Maksimum yeniden deneme |
|---|---|---|
| Sıralı | 1 dakika | 288 |
| Sırasız | 5 dakika | 288 |
TCP için yeniden deneme davranışını yapılandırma
Yeniden denemeyi etkinleştirme
Kümelenmiş tüketim modunda tüketim başarısız olduğunda yeniden denemeyi tetiklemek için MessageListener arayüzünü şu yaklaşımlardan biriyle uygulayın:
**
Action.ReconsumeLaterdeğerini döndürün** (önerilir)nulldeğerini döndürünBir istisna fırlatın
public class MessageListenerImpl implements MessageListener {
@Override
public Action consume(Message message, ConsumeContext context) {
// If the consumption logic throws an exception, the message is retried.
doConsumeMessage(message);
// Method 1: Return Action.ReconsumeLater and retry the message.
return Action.ReconsumeLater;
// Method 2: Return null and retry the message.
return null;
// Method 3: Throw an exception and retry the message.
throw new RuntimeException("Consumer Message exception");
}
}
Yeniden denemeyi devre dışı bırakma
Yeniden iletimi önlemek için tüketim mantığınızda tüm istisnaları yakalayın ve Action.CommitMessage değerini döndürün:
public class MessageListenerImpl implements MessageListener {
@Override
public Action consume(Message message, ConsumeContext context) {
try {
doConsumeMessage(message);
} catch (Throwable e) {
// Catch all exceptions and return CommitMessage to skip retry.
return Action.CommitMessage;
}
// Consumption succeeded.
return Action.CommitMessage;
}
}
Yeniden deneme aralığını ve maksimum yeniden deneme sayısını özelleştirme
Özel yeniden deneme yapılandırması için Java için TCP istemci SDK sürüm 1.2.2 veya üzeri gereklidir. Daha fazla bilgi için bkz. Sürüm notları.
Tüketiciyi başlatmadan önce tüketici özelliklerinde MaxReconsumeTimes ve SuspendTimeMillis değerlerini ayarlayın. Özel yeniden deneme aralıkları yalnızca sıralı mesajlar için geçerlidir. Sırasız mesajlar her zaman önceden tanımlanmış zamanlamayı takip eder.
Properties properties = new Properties();
// Set the maximum number of retries to 20.
properties.put(PropertyKeyConst.MaxReconsumeTimes, "20");
// Set the retry interval to 3,000 milliseconds (ordered messages only).
properties.put(PropertyKeyConst.SuspendTimeMillis, "3000");
Consumer consumer = ONSFactory.createConsumer(properties);
Aynı tüketici grubundaki tüm tüketiciler yeniden deneme yapılandırmasını paylaşır. En son başlatılan tüketici, önceki tüketicilerin yapılandırmasının üzerine yazar. Bir gruptaki tüm tüketicilerin aynı MaxReconsumeTimes ve SuspendTimeMillis değerlerini kullandığından emin olun.
Yeniden deneme sayısını sorgulama
Bir tüketici bir mesaj aldıktan sonra, mesajın kaç kez yeniden denendiğini kontrol etmek için message.getReconsumeTimes() yöntemini çağırın:
public class MessageListenerImpl implements MessageListener {
@Override
public Action consume(Message message, ConsumeContext context) {
// Get the current retry count.
System.out.println(message.getReconsumeTimes());
return Action.CommitMessage;
}
}
En iyi uygulamalar
Varsayılan yeniden deneme değerleriyle başlayın. Sırasız mesajlar için varsayılan zamanlama (16 yeniden deneme boyunca 10 saniyeden 2 saate kadar artan), çoğu geçici hata için iyi çalışır. Sisteminizin gerçek hata modellerini gözlemledikten sonra yalnızca gerekliyse ayarlama yapın.
Ölü mektup kuyruğu izlemesini kurun. Tüm yeniden denemeleri tüketen mesajlar ölü mektup kuyruğuna taşınır. Başarısız mesajları hızlı bir şekilde inceleyip yeniden işleyebilmeniz için bu kuyruğu izleyin ve uyarılar kurun.
Tüketim mantığını idempotent tutun. Yeniden denemeler sırasında mesajlar birden fazla kez teslim edilebileceğinden, tüketicinizin yinelemeli işlemeyi güvenli bir şekilde yönetecek şekilde tasarlandığından emin olun.
Uzun süren tüketimden kaçının. İşlem çok uzun sürerse mesaj zaman aşımına uğrayabilir ve gereksiz bir yeniden denemeyi tetikleyebilir. Uzun görevleri daha küçük adımlara bölün veya tüketim zaman aşımını artırın.
Sonraki adımlar
Ölü mektup kuyrukları -- Tüm yeniden deneme girişimlerinden sonra başarısız olan mesajları işleyin.
Sürüm notları -- TCP istemci SDK sürüm gereksinimlerini kontrol edin.