Ketika produsen mengirimkan pesan ke broker ApsaraMQ for RocketMQ, permintaan tersebut dapat gagal karena masalah jaringan, restart broker, atau batas kapasitas. SDK client menangani kegagalan ini melalui dua mekanisme bawaan:
Sending retry mengirim ulang pesan yang gagal secara otomatis hingga berhasil atau mencapai batas jumlah percobaan ulang.
Throttling melindungi broker dari kelebihan beban dengan menolak permintaan ketika kapasitas tidak mencukupi.
Kedua mekanisme ini bekerja bersama: ketika throttling memicu penolakan, mekanisme retry menggunakan exponential backoff untuk mengirim ulang pesan tanpa memperberat beban broker lebih lanjut.
Sending retry
Proses retry
SDK client menyertakan logika retry bawaan. Ketika permintaan pengiriman gagal, SDK secara otomatis mengirim ulang pesan tersebut—tidak diperlukan kode retry tingkat aplikasi.
Tentukan jumlah maksimum percobaan ulang saat menginisialisasi produsen. Jika permintaan gagal, SDK akan mencoba mengirim ulang hingga pesan berhasil dikirim atau mencapai batas retry. Setelah percobaan terakhir gagal, SDK mengembalikan error ke aplikasi Anda.
Perilaku retry berbeda berdasarkan mode pengiriman:
| Sending mode | Perilaku thread | Pada kegagalan akhir |
|---|---|---|
| Synchronous | Thread pemanggil diblokir selama seluruh rangkaian retry | SDK melemparkan exception |
| Asynchronous | Thread pemanggil tidak diblokir | SDK mengirimkan event callback kegagalan |
Pemicu retry
Retry dipicu oleh dua kategori kegagalan:
Kegagalan sisi client
Exception jaringan menyebabkan kegagalan koneksi atau timeout permintaan.
Broker sedang melakukan restart atau undeploy, sehingga menyebabkan kegagalan koneksi.
Broker berjalan lambat, menyebabkan timeout permintaan.
Error sisi broker
System logic error: Error pemrosesan internal pada broker.
System throttling error: Broker menolak permintaan karena telah melebihi kapasitas. Lihat Throttling.
Pesan transaksional hanya mendukung transparent retries. SDK tidak melakukan retry terhadap pesan transaksional pada exception jaringan atau timeout.
Interval retry
Interval retry bergantung pada jenis error:
| Jenis error | Interval retry |
|---|---|
| Semua error kecuali throttling | Langsung (tanpa penundaan) |
| System throttling error | Exponential backoff dengan jitter |
Untuk error throttling, SDK menggunakan exponential backoff dengan parameter berikut:
| Parameter | Deskripsi | Bawaan |
|---|---|---|
INITIAL_BACKOFF | Penundaan sebelum retry pertama | 1 detik |
MULTIPLIER | Faktor peningkatan penundaan setelah setiap retry | 1,6 |
JITTER | Faktor randomisasi yang diterapkan pada setiap penundaan | 0,2 |
MAX_BACKOFF | Penundaan maksimum antar retry | 120 detik |
MIN_CONNECT_TIMEOUT | Timeout koneksi minimum | 20 detik |
Algoritma backoff bekerja sebagai berikut:
ConnectWithBackoff()
current_backoff = INITIAL_BACKOFF
current_deadline = now() + INITIAL_BACKOFF
while (TryConnect(Max(current_deadline, now() + MIN_CONNECT_TIMEOUT)) != SUCCESS)
SleepUntil(current_deadline)
current_backoff = Min(current_backoff * MULTIPLIER, MAX_BACKOFF)
current_deadline = now() + current_backoff +
UniformRandom(-JITTER * current_backoff, JITTER * current_backoff)Untuk spesifikasi lengkap, lihat gRPC connection backoff.
Pahami anggaran waktu total untuk retry
SDK hanya menyediakan satu kontrol retry: jumlah maksimum percobaan ulang. Dalam mode synchronous, thread pemanggil diblokir selama seluruh rangkaian retry, sehingga total waktu pemblokiran bergantung pada hubungan antara timeout per permintaan dan jumlah maksimum retry:
Total blocking time (kasus terburuk) = max_retries x per_request_timeout + sum_of_backoff_delaysUntuk error non-throttling (retry langsung), penundaan backoff bernilai nol:
Total blocking time = max_retries x per_request_timeoutUntuk error throttling, penundaan backoff bertambah secara eksponensial. Sebagai contoh, dengan parameter bawaan dan 5 kali retry:
| Retry | Penundaan backoff (perkiraan) | Penundaan kumulatif |
|---|---|---|
| 1 | 1 dtk | 1 dtk |
| 2 | 1,6 dtk | 2,6 dtk |
| 3 | 2,56 dtk | 5,16 dtk |
| 4 | 4,1 dtk | 9,26 dtk |
| 5 | 6,55 dtk | 15,81 dtk |
Evaluasi timeout per permintaan dan jumlah maksimum retry secara bersamaan agar thread pemanggil tidak terlalu lama diblokir dalam mode synchronous.
Menangani pesan gagal setelah retry habis
Retry bawaan tidak menjamin pengiriman. Jika semua retry gagal, SDK mengembalikan error. Tangkap error ini di aplikasi Anda dan terapkan strategi fallback:
Tulis pesan yang gagal ke log lokal atau dead-letter store untuk diproses ulang nanti.
Berikan notifikasi ke sistem monitoring Anda agar Anda dapat menyelidiki akar penyebabnya.
Menangani pesan duplikat akibat retry
Ketika permintaan pengiriman mengalami timeout, SDK tidak dapat menentukan apakah broker telah menerima dan menyimpan pesan tersebut. Retry dapat menghasilkan duplikat di broker. Ini merupakan trade-off mendasar dalam sistem pengiriman at-least-once.
Untuk menangani duplikat, rancang konsumen Anda agar mendukung pemrosesan idempoten:
Beri setiap pesan kunci bisnis unik (misalnya ID pesanan atau ID transaksi).
Sebelum memproses, periksa apakah kunci tersebut sudah pernah diproses.
Gunakan constraint database atau cache deduplikasi untuk menegakkan keunikan.
Throttling
Throttling merupakan mekanisme operasional normal dalam sistem messaging cloud. Ketika kapasitas sistem tidak mencukupi atau penggunaan melebihi ambang batas yang telah ditentukan, broker ApsaraMQ for RocketMQ langsung menolak permintaan dan mengembalikan system throttling error. Logika retry bawaan SDK kemudian menangani permintaan yang ditolak tersebut menggunakan exponential backoff.
Pemicu throttling
Throttling dipicu dalam skenario berikut:
Storage pressure surge: Kelompok konsumen mulai mengonsumsi dari offset maksimum suatu antrian. Dalam skenario seperti peluncuran bisnis di mana kelompok konsumen harus mulai mengonsumsi pada waktu tertentu, tekanan penyimpanan pada antrian meningkat tajam. Untuk informasi lebih lanjut, lihat Consumer progress management.
Message accumulation: Ketika konsumen tidak mampu mengimbangi laju pesan masuk, pesan yang belum dikonsumsi menumpuk di antrian. Jika akumulasi melebihi ambang batas, broker memicu throttling untuk mengurangi tekanan pada sistem downstream.
Kode error dan perilaku retry berdasarkan jenis client
Ketika throttling dipicu, kode error dan perilaku retry bergantung pada protokol client Anda.
Client gRPC
| Item | Nilai |
|---|---|
| Kode error | 530 |
| Kata kunci pesan error | TOO_MANY_REQUESTS |
| Perilaku retry | Retry otomatis dengan exponential backoff |
Client Remoting
| Item | Nilai |
|---|---|
| Kode error | 215 |
| Kata kunci pesan error | messages flow control |
Perilaku retry untuk client Remoting bervariasi berdasarkan versi SDK:
| SDK | Perilaku retry saat throttling |
|---|---|
| ApsaraMQ for RocketMQ TCP client SDK for Java < 1.9.0.Final | Tidak ada retry |
| ApsaraMQ for RocketMQ TCP client SDK for Java >= 1.9.0.Final | Retry otomatis dengan exponential backoff |
| Open-source Apache RocketMQ SDK (produsen) | Tidak ada retry |
| Open-source Apache RocketMQ SDK (konsumen) | Retry otomatis dengan exponential backoff |
Jika versi SDK Anda tidak melakukan retry otomatis pada error throttling, terapkan logika retry dengan exponential backoff di kode aplikasi Anda.
Untuk versi client yang didukung, lihat SDK compatibility.
Mencegah dan menangani throttling
Monitor kapasitas sebelum lonjakan traffic
Gunakan fitur observabilitas ApsaraMQ for RocketMQ untuk memantau penggunaan dan kapasitas sistem. Sebelum peluncuran bisnis atau lonjakan traffic yang diprediksi:
Verifikasi bahwa instans Anda memiliki sumber daya yang cukup untuk traffic yang diharapkan.
Periksa lag kelompok konsumen untuk mengidentifikasi risiko akumulasi.
Scale up instans Anda atau optimalkan throughput konsumen jika diperlukan.
Menangani throttling tak terduga saat runtime
Jika throttling terjadi secara tak terduga dan retry bawaan SDK tidak dapat memulihkan kondisi:
Arahkan permintaan ke sistem fallback hingga kondisi throttling mereda.
Catat event throttling (cari kode error
530/TOO_MANY_REQUESTSuntuk gRPC atau215/messages flow controluntuk Remoting) untuk membantu mendiagnosis akar penyebabnya.