Ketika konsumen gagal memproses sebuah pesan atau pemrosesan mengalami timeout, ApsaraMQ for RocketMQ secara otomatis mengirimkan ulang pesan tersebut berdasarkan kebijakan retry. Setelah semua upaya retry habis, pesan tersebut dipindahkan ke dead-letter queue. Anda dapat mengonsumsi pesan dalam dead-letter queue untuk memulihkan bisnis Anda.
Catatan penggunaan
ID pesan tetap tidak berubah selama semua upaya retry.
Retry konsumsi hanya berlaku dalam clustering consumption mode. Dalam broadcasting consumption mode, pesan yang gagal tidak dikirim ulang—konsumen langsung melanjutkan ke pesan berikutnya.
Cara kerja
Sebuah pesan melewati status-status berikut:
| Status | Deskripsi |
|---|---|
| Ready | Pesan berada dalam antrian di broker dan siap dikonsumsi. |
| Inflight | Konsumen telah menarik pesan dan sedang memprosesnya. Belum ada respons yang dikembalikan. |
| WaitingRetry | Konsumsi gagal atau mengalami timeout. Pesan menunggu hingga interval retry berakhir sebelum kembali ke status Ready. |
| Commit | Konsumen mengembalikan respons sukses. Konsumsi selesai. |
| DLQ | Jika fitur penyimpanan pesan dead-letter diaktifkan, pesan dipindahkan ke topik dead-letter setelah semua upaya retry habis. |

Waktu retry
Interval antara dua upaya konsumsi berturut-turut terdiri dari tiga komponen:
Interval antar upaya = durasi pemrosesan + interval retry + waktu dalam status Ready

Sebagai contoh, asumsikan sebuah pesan menunggu 5 detik dalam status Ready dan membutuhkan 6 detik untuk diproses sebelum gagal. Dengan interval retry 10 detik:
0 dtk — Pesan memasuki status Ready.
5 dtk — Konsumen menarik pesan (Inflight).
11 dtk — Konsumsi gagal setelah 6 detik. Pesan memasuki WaitingRetry.
21 dtk — Setelah interval retry 10 detik, pesan kembali ke status Ready.
26 dtk — Konsumen menarik pesan lagi untuk upaya berikutnya.
Total interval: 6 + 10 + 5 = 21 detik.
Kebijakan retry untuk TCP
Pesan terurut
| Pengaturan | Detail |
|---|---|
| Interval Pengulangan | Diatur dengan parameter suspendTimeMillis. Rentang valid: 10 – 30.000 ms. Default: 1.000 ms (1 detik). |
| Maximum Retries | Diatur dengan parameter MaxReconsumeTimes. Tidak ada batas atas. Default: Integer.MAX. |
Pesan tidak terurut
| Pengaturan | Detail |
|---|---|
| Interval percobaan ulang | Mengikuti jadwal eskalasi bawaan (lihat tabel di bawah). Interval kustom tidak didukung untuk pesan tidak terurut. |
| Maksimum percobaan ulang | Diatur dengan parameter MaxReconsumeTimes. Tidak ada batas atas. Default: 16. |
Jika MaxReconsumeTimes melebihi 16, jadwal bawaan berlaku untuk 16 retry pertama. Semua retry berikutnya menggunakan interval tetap 2 jam.
Jadwal interval retry untuk pesan tidak terurut
| Retry | Interval | Retry | Interval |
|---|---|---|---|
| 1 | 10 detik | 9 | 7 menit |
| 2 | 30 detik | 10 | 8 menit |
| 3 | 1 menit | 11 | 9 menit |
| 4 | 2 menit | 12 | 10 menit |
| 5 | 3 menit | 13 | 20 menit |
| 6 | 4 menit | 14 | 30 menit |
| 7 | 5 menit | 15 | 1 jam |
| 8 | 6 menit | 16 | 2 jam |
Kebijakan retry untuk HTTP
Kebijakan retry HTTP telah ditentukan sebelumnya dan tidak dapat diubah.
| Jenis pesan | Retry Interval | Maksimum retry |
|---|---|---|
| Dipesan | 1 menit | 288 |
| Tidak terurut | 5 menit | 288 |
Konfigurasi perilaku retry untuk TCP
Aktifkan retry
Untuk memicu retry saat konsumsi gagal dalam clustering consumption mode, implementasikan antarmuka MessageListener dengan salah satu pendekatan berikut:
Kembalikan
Action.ReconsumeLater(disarankan)Kembalikan
nullLempar exception
public class MessageListenerImpl implements MessageListener {
@Override
public Action consume(Message message, ConsumeContext context) {
// Jika logika konsumsi melempar exception, pesan akan di-retry.
doConsumeMessage(message);
// Metode 1: Kembalikan Action.ReconsumeLater untuk retry pesan.
return Action.ReconsumeLater;
// Metode 2: Kembalikan null untuk retry pesan.
return null;
// Metode 3: Lempar exception untuk retry pesan.
throw new RuntimeException("Consumer Message exception");
}
}Nonaktifkan retry
Untuk mencegah pengiriman ulang, tangkap semua exception dalam logika konsumsi Anda dan kembalikan Action.CommitMessage:
public class MessageListenerImpl implements MessageListener {
@Override
public Action consume(Message message, ConsumeContext context) {
try {
doConsumeMessage(message);
} catch (Throwable e) {
// Tangkap semua exception dan kembalikan CommitMessage untuk melewati retry.
return Action.CommitMessage;
}
// Konsumsi berhasil.
return Action.CommitMessage;
}
}Kustomisasi interval retry dan maksimum retry
Konfigurasi retry kustom memerlukan TCP client SDK untuk Java versi 1.2.2 atau lebih baru. Untuk informasi selengkapnya, lihat Release notes.
Atur MaxReconsumeTimes dan SuspendTimeMillis dalam properti konsumen sebelum memulai konsumen. Interval retry kustom hanya berlaku untuk pesan terurut. Pesan tidak terurut selalu mengikuti jadwal bawaan.
Properties properties = new Properties();
// Atur jumlah maksimum retry menjadi 20.
properties.put(PropertyKeyConst.MaxReconsumeTimes, "20");
// Atur interval retry menjadi 3.000 milidetik (hanya untuk pesan terurut).
properties.put(PropertyKeyConst.SuspendTimeMillis, "3000");
Consumer consumer = ONSFactory.createConsumer(properties);Semua konsumen dalam kelompok konsumen yang sama berbagi konfigurasi retry. Konsumen yang paling baru dimulai akan menimpa konfigurasi konsumen sebelumnya. Pastikan semua konsumen dalam satu kelompok menggunakan nilai MaxReconsumeTimes dan SuspendTimeMillis yang identik.
Periksa jumlah retry
Setelah konsumen menerima pesan, panggil message.getReconsumeTimes() untuk memeriksa berapa kali pesan tersebut telah di-retry:
public class MessageListenerImpl implements MessageListener {
@Override
public Action consume(Message message, ConsumeContext context) {
// Dapatkan jumlah retry saat ini.
System.out.println(message.getReconsumeTimes());
return Action.CommitMessage;
}
}Praktik terbaik
Mulai dengan nilai retry default. Jadwal default untuk pesan tidak terurut (meningkat dari 10 detik hingga 2 jam dalam 16 retry) bekerja baik untuk sebagian besar kegagalan sementara. Lakukan penyesuaian hanya setelah mengamati pola kegagalan aktual sistem Anda.
Siapkan pemantauan dead-letter queue. Pesan yang habis semua retry-nya dipindahkan ke dead-letter queue. Pantau antrian ini dan atur peringatan agar Anda dapat segera menyelidiki dan memproses ulang pesan yang gagal.
Buat logika konsumsi idempoten. Karena pesan mungkin dikirim lebih dari sekali selama retry, rancang konsumen Anda agar dapat menangani pemrosesan duplikat secara aman.
Hindari konsumsi berdurasi panjang. Jika pemrosesan memakan waktu terlalu lama, pesan mungkin mengalami timeout dan memicu retry yang tidak perlu. Pecah tugas panjang menjadi langkah-langkah kecil atau tingkatkan timeout konsumsi.
Langkah selanjutnya
Dead-letter queues — Tangani pesan yang gagal setelah semua upaya retry habis.
Release notes — Periksa persyaratan versi TCP client SDK.