All Products
Search
Document Center

ApsaraMQ for RocketMQ:Pengulangan pesan

Last Updated:Mar 12, 2026

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:

StatusDeskripsi
ReadyPesan berada dalam antrian di broker dan siap dikonsumsi.
InflightKonsumen telah menarik pesan dan sedang memprosesnya. Belum ada respons yang dikembalikan.
WaitingRetryKonsumsi gagal atau mengalami timeout. Pesan menunggu hingga interval retry berakhir sebelum kembali ke status Ready.
CommitKonsumen mengembalikan respons sukses. Konsumsi selesai.
DLQJika fitur penyimpanan pesan dead-letter diaktifkan, pesan dipindahkan ke topik dead-letter setelah semua upaya retry habis.
TCP message state diagram

Waktu retry

Interval antara dua upaya konsumsi berturut-turut terdiri dari tiga komponen:

Interval antar upaya = durasi pemrosesan + interval retry + waktu dalam status Ready

Retry interval timing diagram

Sebagai contoh, asumsikan sebuah pesan menunggu 5 detik dalam status Ready dan membutuhkan 6 detik untuk diproses sebelum gagal. Dengan interval retry 10 detik:

  1. 0 dtk — Pesan memasuki status Ready.

  2. 5 dtk — Konsumen menarik pesan (Inflight).

  3. 11 dtk — Konsumsi gagal setelah 6 detik. Pesan memasuki WaitingRetry.

  4. 21 dtk — Setelah interval retry 10 detik, pesan kembali ke status Ready.

  5. 26 dtk — Konsumen menarik pesan lagi untuk upaya berikutnya.

Total interval: 6 + 10 + 5 = 21 detik.

Kebijakan retry untuk TCP

Pesan terurut

PengaturanDetail
Interval PengulanganDiatur dengan parameter suspendTimeMillis. Rentang valid: 10 – 30.000 ms. Default: 1.000 ms (1 detik).
Maximum RetriesDiatur dengan parameter MaxReconsumeTimes. Tidak ada batas atas. Default: Integer.MAX.

Pesan tidak terurut

PengaturanDetail
Interval percobaan ulangMengikuti jadwal eskalasi bawaan (lihat tabel di bawah). Interval kustom tidak didukung untuk pesan tidak terurut.
Maksimum percobaan ulangDiatur 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

RetryIntervalRetryInterval
110 detik97 menit
230 detik108 menit
31 menit119 menit
42 menit1210 menit
53 menit1320 menit
64 menit1430 menit
75 menit151 jam
86 menit162 jam

Kebijakan retry untuk HTTP

Kebijakan retry HTTP telah ditentukan sebelumnya dan tidak dapat diubah.

Jenis pesanRetry IntervalMaksimum retry
Dipesan1 menit288
Tidak terurut5 menit288

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 null

  • Lempar 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

Catatan

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);
Penting

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