Circuit breaker mengubah keputusan admission untuk panggilan keluar sebelum dependency menerimanya. Pada state closed, panggilan diteruskan dan hasilnya menjadi input bagi kebijakan kegagalan. Setelah kebijakan tersebut terpicu, breaker masuk ke state open dan menolak panggilan berikutnya secara lokal. Setelah interval pemulihan yang dikonfigurasi berakhir, sejumlah terbatas panggilan probe dapat menguji apakah dependency sudah dapat dipakai kembali.

Mekanisme ini berbeda dari retry. Retry mengirim percobaan lain setelah sebuah percobaan gagal. Breaker dapat mencegah sebuah percobaan dikirim sama sekali. Menggabungkan keduanya tanpa urutan yang presisi dapat memperbesar trafik saat terjadi gangguan atau mempertahankan breaker dalam state open berdasarkan sinyal yang tidak merepresentasikan kondisi dependency.

State breaker berada pada batas panggilan

Breaker yang berguna mengelilingi satu operasi dependency dengan kegagalan yang memiliki makna sebanding. Batas yang dilindungi dapat berupa panggilan ke satu remote service, satu endpoint database, atau satu operasi API eksternal. Satu breaker yang dipakai bersama untuk tujuan yang tidak berkaitan dapat menggabungkan failure domain yang independen: masalah pada satu tujuan dapat menekan panggilan ke tujuan lain yang sehat.

State machine biasanya memiliki tiga state konseptual:

State Perilaku admission Input state
Closed Menerima panggilan normal Hasil yang dicatat dapat memicu kebijakan kegagalan
Open Menolak panggilan secara lokal Waktu atau kondisi pemulihan eksplisit lain mengizinkan probing
Half-open Menerima probe dalam jumlah terbatas Hasil probe menutup atau membuka kembali breaker

Kebijakan transisi yang tepat bersifat spesifik terhadap implementasi. Breaker dapat memakai kegagalan berurutan, rasio dalam rolling window, jumlah sampel minimum, ambang latency, atau kelas error tertentu. Pilihan tersebut tidak setara. Rasio dari dua panggilan memiliki makna statistik yang sangat berbeda dari rasio yang sama atas ratusan panggilan, sehingga kebijakan praktis sering menetapkan volume minimum sebelum breaker terpicu.

Klasifikasi kegagalan menentukan sinyal

Tidak setiap hasil aplikasi yang gagal menandakan dependency yang bermasalah. HTTP 404 dapat menjadi respons domain yang valid. HTTP 429 dapat menandakan tekanan kapasitas dan mungkin perlu diperlakukan berbeda dari request tidak valid yang menerima 400. Connection refusal, transport timeout, dan respons 5xx tertentu dapat menjadi bukti lebih kuat bahwa percobaan lain kecil kemungkinannya berhasil dalam waktu dekat.

Karena itu, breaker memerlukan fungsi klasifikasi eksplisit. Secara konseptual:

result = call_dependency()

if result indicates dependency failure:
    breaker.record_failure()
else:
    breaker.record_success()

Klasifikasi harus sesuai dengan operasi yang dilindungi. Menganggap setiap status non-success sebagai kegagalan breaker dapat mengubah client error normal menjadi penekanan infrastruktur. Mengabaikan transport failure menghasilkan efek sebaliknya: breaker tetap closed sementara caller terus menghabiskan budget koneksi dan timeout pada dependency yang tidak merespons.

Timeout juga memerlukan pemilik yang jelas. Jika caller meninggalkan request karena deadline miliknya sementara dependency kemudian selesai dengan sukses, kebijakan breaker harus menetapkan observasi mana yang dihitung. Library dapat memiliki perilaku berbeda, dan propagasi cancellation dapat mengubah hasil yang terlihat pada batas breaker.

State open mengubah biaya remote menjadi penolakan lokal

Saat breaker open, penolakan terjadi tanpa menunggu operasi remote yang dilindungi. Kondisi ini mengubah konsumsi resource sekaligus semantik error. Socket, stream, query database, atau remote request baru tidak perlu dibuat untuk panggilan yang ditolak, dengan asumsi resource tersebut diperoleh di dalam batas yang dilindungi.

Penolakan lokal sebaiknya tetap dapat dibedakan dari kegagalan remote. Caller dapat memakai perbedaan tersebut untuk metric, pemilihan fallback, atau pemetaan respons. Menyatukan “breaker open” dengan error yang sama seperti “remote timeout” menyembunyikan informasi apakah pekerjaan pernah mencapai dependency.

Penolakan state open bukan jaminan durability atau delivery. Artinya hanya breaker menolak panggilan tersebut. Jika operasi merepresentasikan pekerjaan yang wajib dijalankan, mekanisme lain harus menetapkan persistence, queueing, compensation, atau eksekusi pada waktu berikutnya.

Admission half-open merupakan kontrak concurrency

Melewatkan semua caller yang menunggu segera setelah interval pemulihan berakhir dapat menciptakan kembali overload awal. State half-open membatasi transisi tersebut. Breaker dapat menerima satu probe, sejumlah kecil probe tetap, atau jumlah bounded work lain secara concurrent sambil menolak atau menahan sisanya.

Batas tersebut memerlukan koordinasi atomic ketika banyak thread, goroutine, process, atau task event loop memakai breaker yang sama. Pemeriksaan yang diikuti increment terpisah dapat melampaui jumlah probe yang dimaksud akibat race:

if probes_in_flight < probe_limit:
    probes_in_flight += 1
    send_probe()

Dua caller dapat melihat nilai lama yang sama sebelum salah satu increment terlihat. Implementasi umumnya melindungi state ini dengan lock, atomic operation, atau ownership yang dibatasi pada satu execution context terserialisasi.

Breaker process-local hanya mengoordinasikan caller di process tersebut. Sepuluh instance aplikasi dengan batas satu probe half-open masih dapat menghasilkan hingga sepuluh probe concurrent. Deployment yang memerlukan batas cluster-wide membutuhkan shared coordination atau mekanisme admission lain. State process-local tidak boleh dinyatakan sebagai batas terdistribusi.

Retry mengubah observasi yang diterima breaker

Penempatan breaker terhadap retry loop mengubah apa yang dihitung. Dengan breaker di luar mekanisme retry, satu logical request dapat menghasilkan satu outcome tercatat setelah beberapa percobaan. Dengan breaker mengelilingi setiap percobaan, setiap percobaan gagal dapat berkontribusi secara terpisah pada kebijakan breaker.

Pertimbangkan client yang dikonfigurasi untuk tiga percobaan:

breaker(
    retry_up_to_three_times(remote_call)
)

Bentuk ini dapat mengekspos hanya hasil retry terakhir kepada breaker. Jika komposisinya dibalik:

retry_up_to_three_times(
    breaker(remote_call)
)

setiap percobaan yang diterima dapat masuk ke accounting breaker, bergantung pada API library. Setelah breaker open, iterasi retry berikutnya dapat menerima penolakan state open lokal alih-alih mencapai remote service.

Tidak ada satu komposisi yang selalu tepat. Sinyal yang dituju menentukan batasnya. Perlindungan tingkat percobaan bereaksi lebih cepat terhadap kegagalan remote berulang, tetapi mengikat statistik breaker pada konfigurasi retry. Perlindungan tingkat request memperlakukan kebijakan retry sebagai satu operasi, tetapi dapat menyembunyikan beban berulang yang diberikan kepada dependency.

Interval pemulihan bukan health check

Timer yang menggerakkan breaker dari open menuju half-open tidak membuktikan bahwa dependency telah pulih. Timer hanya memberikan izin untuk menguji lagi. Menutup breaker sebelum mengamati probe yang sukses mengubah waktu yang berlalu menjadi asumsi kondisi sehat tanpa bukti.

Keberhasilan probe juga memerlukan ambang yang ditetapkan. Satu request sukses mungkin cukup untuk kebijakan sederhana, sedangkan sistem lain dapat mensyaratkan beberapa probe sukses sebelum memulihkan admission penuh. Pilihan ini menukar kecepatan pemulihan dengan risiko mengirim trafik normal ke dependency yang baru tersedia sebagian.

Interval pemulihan tetap juga dapat menyinkronkan banyak client. Jika banyak instance terpicu pada waktu yang hampir sama dan memakai interval yang sama, probe mereka dapat sejajar. Jitter atau timing khusus per instance dapat mengurangi sinkronisasi tersebut, tetapi kebijakan tepatnya tetap merupakan pilihan deployment, bukan properti bawaan pola breaker.

Metric memerlukan dimensi state dan outcome

Breaker mengubah trafik sebelum telemetry remote dapat mengamatinya. Selama interval open, dependency dapat menunjukkan lebih sedikit request gagal hanya karena caller berhenti mengirimnya. Karena itu, error rate dari sisi service saja tidak dapat menggambarkan availability dari sisi caller.

Observasi yang berguna mencakup transisi state breaker, jumlah penolakan lokal, outcome panggilan yang diterima, outcome probe, dan waktu yang dihabiskan pada setiap state. Sinyal ini sebaiknya mempertahankan identitas batas dependency yang dilindungi tanpa menciptakan cardinality metric yang tidak terbatas.

Jumlah penolakan lokal yang tinggi bersama trafik remote yang rendah dapat menjadi kondisi yang diharapkan selama interval open. Breaker yang berulang kali berganti antara half-open dan open menunjukkan probe terus gagal atau kriteria penutupan terlalu permisif untuk kondisi dependency saat ini. Interpretasi metric mengikuti state machine secara langsung.

Scope breaker menentukan failure domain

Pengaturan breaker yang paling berdampak sering bukan ambang numerik, melainkan scope shared state. Breaker per request hampir tidak memiliki memori lintas panggilan. Breaker yang dibagikan ke semua outbound dependency dapat menekan trafik yang tidak berkaitan. Breaker per endpoint, kelas operasi, atau tenant dapat mengisolasi kegagalan dengan lebih presisi, tetapi menghasilkan lebih banyak state dan dimensi operasional.

Scope sebaiknya sesuai dengan resource atau dependency yang availability-nya benar-benar direpresentasikan oleh outcome tercatat. Setelah batas tersebut eksplisit, threshold, interval pemulihan, concurrency probe, komposisi retry, dan telemetry dapat dievaluasi terhadap failure domain yang sama alih-alih disetel sebagai parameter yang terpisah.