Jika konsumen mengalami pengecualian, ApsaraMQ for RocketMQ mengirim ulang pesan berdasarkan kebijakan retry konsumsi untuk memulihkan kesalahan. Topik ini menjelaskan kasus penggunaan, mekanisme kerja, kompatibilitas versi, dan rekomendasi penggunaan fitur retry konsumsi.
Skenario
ApsaraMQ for RocketMQ menggunakan retry konsumsi terutama untuk menangani ketidaklengkapan pemrosesan pesan akibat kegagalan dalam logika bisnis. Fitur ini merupakan strategi cadangan bagi bisnis Anda dan tidak boleh digunakan sebagai bagian dari pengendalian alur bisnis.
-
Gunakan retry pesan dalam skenario berikut:
-
Pemrosesan bisnis gagal, dan kegagalan tersebut terkait dengan konten pesan saat ini—misalnya, resolusi transaksi untuk pesan ini belum diperoleh, tetapi keberhasilan diharapkan setelah penundaan singkat.
-
Penyebab kegagalan konsumsi bersifat non-sistemik—artinya pesan saat ini gagal karena kejadian langka, bukan kegagalan konsisten—dan pesan berikutnya kemungkinan besar akan berhasil. Dalam hal ini, retry pesan saat ini mencegah proses terblokir.
-
-
Hindari retry pesan dalam skenario berikut:
-
Menggunakan kegagalan konsumsi sebagai cabang kondisional dalam logika pemrosesan tidak masuk akal karena logika tersebut sudah mengantisipasi kemunculan cabang ini secara sering.
-
Menggunakan kegagalan konsumsi untuk menerapkan rate limiting tidak tepat. Rate limiting bertujuan untuk sementara waktu mengantrikan traffic berlebih guna meratakan beban puncak—bukan untuk mengarahkan pesan ke jalur retry.
-
Tujuan
Saat perangkat lunak perantara berorientasi pesan digunakan untuk penguraian keterkaitan asinkron, tantangan utamanya adalah memastikan integritas rantai pemanggilan jika layanan downstream gagal memproses pesan. ApsaraMQ for RocketMQ, sebagai perangkat lunak perantara berorientasi pesan yang andal pada tingkat finansial, dirancang secara inheren untuk mendukung strategi transmisi andal dalam mekanisme pemrosesan pengiriman pesannya, sehingga memastikan setiap pesan diproses sesuai harapan bisnis melalui mekanisme acknowledgment dan retry yang lengkap.
Memahami mekanisme acknowledgment pesan dan kebijakan retry konsumsi ApsaraMQ for RocketMQ dapat membantu Anda menganalisis isu-isu berikut:
-
Bagaimana menjamin pemrosesan pesan yang lengkap: Mengetahui kebijakan retry membantu Anda merancang logika konsumen yang memastikan setiap pesan diproses sepenuhnya, mencegah pesan terabaikan dan ketidakkonsistenan status bisnis.
-
Bagaimana memulihkan status pesan selama kegagalan sistem: Hal ini menjelaskan cara status pesan yang sedang diproses (in-flight) dipulihkan selama anomali sistem (seperti gangguan) dan apakah ketidakkonsistenan status dapat terjadi.
Kebijakan Retry Konsumsi
Kebijakan retry konsumsi menentukan interval retry dan jumlah maksimum retry setelah konsumen gagal memproses pesan.
Pemicu Retry
-
Kegagalan konsumsi, termasuk mengembalikan status kegagalan atau melemparkan pengecualian tak terduga.
-
Timeout pemrosesan pesan, termasuk timeout antrian pada PushConsumer.
Perilaku Upaya Ulang Utama
-
Mesin keadaan retry: Mengontrol status pesan dan transisinya selama retry.
-
Interval retry: Waktu antara kegagalan konsumsi (atau timeout) hingga pesan tersedia kembali untuk dikonsumsi ulang.
-
Jumlah maksimum retry: Jumlah maksimum kali sebuah pesan dapat di-retry.
Perbedaan kebijakan retry pesan
Mekanisme dan metode konfigurasi retry berbeda berdasarkan jenis konsumen sebagai berikut:
|
Jenis konsumen |
Mesin keadaan retry |
Interval retry |
Jumlah maksimum retry |
|
PushConsumer |
|
Dikontrol oleh metadata saat pembuatan kelompok konsumen.
|
Diatur melalui Konsol atau OpenAPI |
|
SimpleConsumer |
|
Atur durasi invisible saat mengambil pesan melalui API. |
Diatur melalui Konsol atau OpenAPI |
Untuk kebijakan retry detail, lihat Kebijakan retry konsumsi PushConsumer dan Kebijakan retry konsumsi SimpleConsumer.
Kebijakan Retry Konsumsi PushConsumer
Mesin Keadaan Retry
Saat PushConsumer memproses pesan, pesan bertransisi melalui status berikut:
Ready: Status siap.
Pesan siap di server ApsaraMQ for RocketMQ dan dapat dikonsumsi oleh konsumen.
Inflight: Status pemrosesan.
Inflight: Pesan telah diambil oleh klien konsumen dan sedang diproses, tetapi belum mengembalikan hasil konsumsi.
WaitingRetry: status menunggu retry, yaitu status khusus untuk konsumen push.
WaitingRetry: Status khusus PushConsumer yang dipicu ketika pemrosesan pesan gagal atau timeout. Jika jumlah retry saat ini belum mencapai maksimum, pesan memasuki WaitingRetry. Setelah interval retry, pesan kembali ke Ready untuk dikonsumsi ulang. Interval retry meningkat seiring jumlah percobaan untuk mencegah retry frekuensi tinggi pada kegagalan persisten.
Commit: status commit.
Commit: Menunjukkan konsumsi berhasil. Mesin keadaan pesan berakhir ketika konsumen mengembalikan respons sukses.
DLQ: dead-letter queue.
DLQ: Status dead-letter—fallback terakhir. Jika jumlah retry melebihi batas maksimum dan retensi pesan dead-letter diaktifkan, pesan yang gagal dikirim ke topik dead-letter. Anda dapat mengonsumsi pesan dari topik ini untuk memulihkan operasi bisnis. Untuk detailnya, lihat Pesan dead-letter.
Discard: Buang.
Discard: Jika jumlah retry melebihi batas maksimum dan retensi dead-letter dinonaktifkan, pesan dibuang.

Contoh: Pada diagram di atas, asumsikan pesan berada dalam status Ready selama 5 detik dan memerlukan 6 detik untuk diproses.
Setiap siklus retry mengikuti alur Ready → Inflight → WaitingRetry. Interval retry adalah waktu antara kegagalan (atau timeout) hingga pesan kembali menjadi Ready. Waktu aktual antara dua upaya konsumsi juga mencakup waktu pemrosesan dan durasi Ready. Contohnya:
-
Pada detik ke-0, pesan memasuki status Ready.
-
Karena kecepatan pemrosesan konsumen, konsumsi dimulai pada detik ke-5. Setelah 6 detik (pada detik ke-11), terjadi pengecualian dan klien mengembalikan kegagalan.
-
Retry tidak dapat dimulai segera—harus menunggu interval retry.
-
Pada detik ke-21, pesan kembali menjadi Ready.
-
Klien mulai mengonsumsi ulang 5 detik kemudian.
Oleh karena itu, interval aktual antara dua upaya konsumsi adalah: waktu pemrosesan + interval retry + durasi Ready = 21 detik.
Interval Retry
-
Pesan tidak terurut (pesan non-terurut): Interval retry menggunakan pendekatan waktu bertahap, sebagai berikut:
Upaya Coba Lagi
Interval retry
Upaya Coba Lagi
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
CatatanJika upaya retry melebihi 16, semua retry berikutnya menggunakan interval 2 jam.
-
Pesan terurut: Gunakan interval retry tetap. Untuk nilai spesifiknya, lihat Batas parameter.
Jumlah Coba Ulang Maksimum
Untuk PushConsumer, jumlah maksimum retry dikontrol oleh metadata kelompok konsumen. Untuk mengubahnya, lihat Ubah jumlah maksimum retry.
Sebagai contoh, jika jumlah maksimum retry adalah 3, pesan dikirim hingga 4 kali: sekali awal dan tiga kali melalui retry.
Contoh Penggunaan
Untuk memicu retry di PushConsumer, cukup kembalikan kode status kegagalan konsumsi. Pengecualian tak terduga secara otomatis ditangkap oleh SDK.
SimpleConsumer simpleConsumer = null;
// Contoh konsumsi: Gunakan PushConsumer untuk mengonsumsi pesan normal. Kembalikan error saat gagal untuk memicu retry.
MessageListener messageListener = new MessageListener() {
@Override
public ConsumeResult consume(MessageView messageView) {
System.out.println(messageView);
// Kembalikan FAILURE untuk memicu retry otomatis hingga mencapai jumlah maksimum retry.
return ConsumeResult.FAILURE;
}
};
Lihat Log Retry Konsumsi
Untuk pesan terurut, PushConsumer melakukan retry di sisi klien. Server tidak dapat mengakses log retry detail. Jika jejak pesan menunjukkan kegagalan pengiriman untuk pesan terurut, periksa log klien konsumen untuk informasi jumlah maksimum retry dan klien.
Untuk lokasi log klien, lihat Konfigurasi log.
Cari kata kunci berikut di log klien untuk menemukan detail kegagalan konsumsi dengan cepat:
Message listener raised an exception while consuming messages
Failed to consume fifo message finally, run out of attempt times
Kebijakan Retry Konsumsi SimpleConsumer
Mesin Keadaan Retry
Saat SimpleConsumer memproses pesan, pesan bertransisi melalui status berikut:
Ready: Status siap.
Pesan siap di server ApsaraMQ for RocketMQ dan dapat dikonsumsi oleh konsumen.
Inflight: Status pemrosesan.
Inflight: Pesan telah diambil oleh klien konsumen dan sedang diproses, tetapi belum mengembalikan hasil konsumsi.
Commit: status commit.
Commit: Menunjukkan konsumsi berhasil. Mesin keadaan pesan berakhir ketika konsumen mengembalikan respons sukses.
DLQ: dead-letter queue.
DLQ: Status dead-letter—fallback terakhir. Jika jumlah retry melebihi batas maksimum dan retensi pesan dead-letter diaktifkan, pesan yang gagal dikirim ke topik dead-letter. Anda dapat mengonsumsi pesan dari topik ini untuk memulihkan operasi bisnis. Untuk detailnya, lihat Pesan dead-letter.
Discard: Buang.
Discard: Jika jumlah retry melebihi batas maksimum dan retensi dead-letter dinonaktifkan, pesan dibuang.
Berbeda dengan PushConsumer, SimpleConsumer menggunakan interval retry yang dialokasikan sebelumnya. Saat mengambil pesan, konsumen mengatur parameter InvisibleDuration—waktu pemrosesan maksimum yang diizinkan. Saat terjadi kegagalan, interval retry berikutnya menggunakan kembali nilai ini tanpa konfigurasi tambahan.

Karena InvisibleDuration dialokasikan sebelumnya, nilainya mungkin sangat berbeda dari waktu pemrosesan aktual. Anda dapat mengubahnya melalui API.
Sebagai contoh, jika awalnya Anda mengatur waktu pemrosesan menjadi 20 ms tetapi pemrosesan aktual melebihi ini, perpanjang InvisibleDuration untuk menghindari retry prematur.
Untuk mengubah InvisibleDuration, kondisi berikut harus dipenuhi:
-
Pemrosesan pesan belum timeout.
-
Status konsumsi belum di-commit.
Seperti yang ditunjukkan di bawah, InvisibleDuration baru langsung berlaku—menyetel ulang timer invisibility sejak panggilan API dilakukan.

Interval Retry
Interval retry = InvisibleDuration − Waktu pemrosesan aktual
SimpleConsumer mengontrol interval retry melalui InvisibleDuration. Sebagai contoh, jika InvisibleDuration adalah 30 ms dan pemrosesan gagal setelah 10 ms, retry berikutnya terjadi setelah 20 ms. Jika pemrosesan tidak selesai dalam 30 ms dan tidak ada hasil yang dikembalikan, pesan timeout dan langsung di-retry (interval 0 ms).
Jumlah Upaya Ulang Maksimum
Untuk SimpleConsumer, jumlah maksimum retry dikontrol oleh metadata kelompok konsumen saat pembuatan. Untuk mengubahnya, lihat Ubah jumlah maksimum retry.
Sebagai contoh, jika jumlah maksimum retry adalah 3, pesan dikirim hingga 4 kali: sekali awal dan tiga kali melalui retry.
Contoh Penggunaan
Untuk memicu retry di SimpleConsumer, cukup tunggu.
// Contoh konsumsi: Gunakan SimpleConsumer untuk mengonsumsi pesan normal. Untuk memicu retry, diam saja dan biarkan pesan timeout. Server akan secara otomatis melakukan retry.
List<MessageView> messageViewList = null;
try {
messageViewList = simpleConsumer.receive(10, Duration.ofSeconds(30));
messageViewList.forEach(messageView -> {
System.out.println(messageView);
// Saat gagal, abaikan pesan. Pesan akan kembali terlihat dan di-retry.
});
} catch (ClientException e) {
// Jika pull gagal karena throttling atau masalah sistem lainnya, lakukan retry permintaan receive.
e.printStackTrace();
}
Ubah Jumlah Maksimum Retry
Gunakan metode berikut untuk mengubah jumlah maksimum retry untuk PushConsumer dan SimpleConsumer.
1. Jika klien Anda menggunakan protokol Remoting, jumlah maksimum retry aktual mengikuti pengaturan sisi klien, dan konfigurasi ini tidak berpengaruh. Jika klien Anda menggunakan gRPC, pengaturan di sini berlaku.
2. Strategi retry (exponential backoff atau interval tetap) hanya berlaku untuk klien gRPC dan tidak berpengaruh pada klien Remoting.
SDK gRPC
-
Ubah melalui OpenAPI: Perbarui kelompok konsumen
-
Ubah melalui Konsol:
Untuk mengakses pengaturan:
-
Pada halaman Instances, klik nama instans target.
-
Di panel navigasi kiri, klik Groups. Pada halaman Groups, klik Create Group.
Pada dialog Create Group, atur Group ID (1–60 karakter), Delivery Order (Concurrent Delivery atau Ordered Delivery), dan Description. Perluas Advanced Settings untuk mengonfigurasi kebijakan retry sebagai Exponential Backoff, atur Maximum Retry Count (default: 16), dan aktifkan/nonaktifkan Retain Dead-letter Messages (default: off; jika off, pesan yang melebihi jumlah retry akan dibuang).
-
SDK Remoting
-
Ubah melalui parameter SDK Remoting: Atur properti maxReconsumeTimes pada konsumen.
Praktik Terbaik
Retry Secara Wajar—Hindari Menggunakan Retry untuk Rate Limiting
Seperti disebutkan dalam Skema Penggunaan, retry pesan cocok untuk kegagalan bisnis langka—bukan kegagalan sistemik atau berkelanjutan seperti rate limiting.
-
Contoh salah:
Jika laju konsumsi memicu throttling, kembalikan kegagalan dan tunggu retry.
-
Contoh benar:
Jika laju konsumsi memicu throttling, tunda pengambilan pesan dan konsumsi nanti.
Pertanyaan Umum tentang Retry Pesan
Bagaimana Cara Mengatur Timeout Konsumsi Pesan?
Protokol gRPC
-
SimpleConsumer: Rentang timeout adalah 10 detik hingga 12 jam.
Contoh kode:
private long minInvisiableTimeMillsForRecv = Duration.ofSeconds(10).toMillis(); private long maxInvisiableTimeMills = Duration.ofHours(12).toMillis(); -
PushConsumer: Default adalah 230 menit dan tidak dapat diubah.
Protokol Remoting
consumer.setConsumeTimeout(15); // Satuan: menit. Rentang: 1–180 menit