← Semua pembelajaran / Blockchain Nol → RWA
Fase 5 · Deployment & Arsitektur AWS

Failover RPC & resiliency

Penutup course ini: seluruh arsitektur yang sudah kamu bangun — API, KMS, worker, indexer — bergantung pada satu asumsi diam-diam bahwa node provider selalu tersedia. Materi ini menantang asumsi itu.

Sumber asli ethereum.org Resmi Rangkuman ~7 menit baca

Intisari

  • Satu node provider (Fase 3) adalah single point of failure — downtime atau rate-limit provider berarti seluruh fitur on-chain aplikasimu ikut lumpuh.
  • Pola standarnya: rantai fallback — provider utama, provider cadangan, dan opsional node self-hosted sebagai lapisan terakhir.
  • Circuit breaker: setelah beberapa kegagalan berturut-turut dari satu provider, berhenti mencobanya untuk sementara (bukan terus mencoba dan memperlambat semua request) sebelum mencoba lagi.
  • Rate limit (HTTP 429) butuh exponential backoff, bukan retry langsung berulang — retry agresif ke provider yang sudah membatasimu hanya memperpanjang periode pembatasan.
  • Read (Fase 3) jauh lebih mudah di-failover daripada write — panggilan eth_call ke provider mana pun akan memberi hasil yang sama; transaksi yang sudah terkirim ke satu provider tetap harus dilacak lewat hash-nya, bukan dikirim ulang begitu saja ke provider lain.

Rantai fallback

Request masuk
    │
    ▼
Provider utama (mis. Alchemy)  ──gagal/timeout──▶  Provider cadangan (mis. Infura)
                                                          │
                                              ──gagal/timeout──▶  Node self-hosted (opsional)
                                                                        │
                                                          ──gagal──▶  Alert ke tim operasional

Circuit breaker: berhenti mencoba yang jelas sedang bermasalah

Tanpa circuit breaker, aplikasi yang terus mencoba provider yang sedang down akan menghabiskan waktu tunggu (timeout) di setiap request — memperlambat semua pengguna, bukan cuma yang kebetulan kena request pertama yang gagal. Circuit breaker "membuka" setelah beberapa kegagalan berturut-turut, langsung melompat ke provider berikutnya tanpa mencoba yang bermasalah lagi untuk sementara waktu.

public class ProviderDenganFallback {
    private final List<Web3j> providers;   // urut dari prioritas tertinggi
    private final Map<Integer, Integer> kegagalanBerturut = new ConcurrentHashMap<>();
    private static final int AMBANG_BATAS = 3;

    public EthBlock.Block ambilBlockTerbaru() throws IOException {
        for (int i = 0; i < providers.size(); i++) {
            if (kegagalanBerturut.getOrDefault(i, 0) >= AMBANG_BATAS) {
                continue;   // circuit "terbuka" — lewati sementara
            }
            try {
                EthBlock.Block hasil = providers.get(i)
                    .ethGetBlockByNumber(DefaultBlockParameterName.LATEST, false)
                    .send()
                    .getBlock();
                kegagalanBerturut.put(i, 0);   // sukses — reset counter
                return hasil;
            } catch (IOException e) {
                kegagalanBerturut.merge(i, 1, Integer::sum);
                log.warn("Provider {} gagal ({}x berturut), coba berikutnya", i,
                          kegagalanBerturut.get(i));
            }
        }
        throw new IOException("Semua provider gagal — eskalasi ke node self-hosted atau alert");
    }
}

Rate limit: backoff, bukan retry membabi buta

HTTP 429 bukan kegagalan biasa — itu instruksi eksplisit "pelan-pelan". Retry langsung berulang ke provider yang baru saja membatasimu hanya memperpanjang periode pembatasan, dan di beberapa provider bisa mengeskalasi jadi pembatasan yang lebih lama. Pola yang benar: exponential backoff — tunggu 1 detik, gagal lagi tunggu 2 detik, gagal lagi tunggu 4 detik, dst., dengan batas maksimum — sebelum akhirnya melompat ke provider fallback kalau backoff pun tidak membantu.

Read vs write saat failover — bedanya penting

Read (eth_call)Write (eth_sendRawTransaction)
Aman di-retry ke provider lain?Ya — hasilnya selalu sama, provider mana punHati-hati — transaksi mungkin sudah terkirim provider pertama sebelum timeout terjadi
Kalau provider A timeout tapi transaksi mungkin sudah masuk mempoolTidak relevanCek dulu eth_getTransactionByHash di provider lain sebelum mengirim ulang — jangan asumsikan gagal
Konsekuensi kirim ulang yang keliruTidak ada — idempoten secara alamiBerpotensi transaksi terkirim dua kali (kalau nonce berbeda) atau gagal karena nonce bentrok

Ini alasan kenapa Fase 5.3 menekankan penyimpanan status di database, bukan hanya di memori. Kalau worker tidak yakin apakah transaksi terkirim sebelum koneksi ke provider terputus, langkah pertama selalu memeriksa status hash transaksi (kalau sempat tercatat) lewat provider mana pun — bukan langsung menandatangani dan mengirim transaksi baru dengan nonce yang sama.

Latihan: konfigurasikan dua provider RPC testnet (mis. Alchemy sebagai utama, Infura sebagai cadangan) di kelas ProviderDenganFallback di atas. Simulasikan kegagalan provider utama (mis. pakai URL yang salah sengaja) dan verifikasi permintaan otomatis jatuh ke provider cadangan tanpa perlu restart aplikasi atau intervensi manual — inilah penutup dari seluruh arsitektur yang sudah kamu bangun sepanjang course ini.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.