失敗から学ぶサーキットブレーカーの仕組み
数日前、予期せぬ問題に直面しました。
強い挫折感を感じました。どうしても解決したかった。そして、好奇心に駆られて、調査を続けました。
再び問題に向き合い、解決策を見つけました。それは「サーキットブレーカー(Circuit Breaker)」と呼ばれるものです。
ソフトウェアにおけるサーキットブレーカーは、単一の障害がシステム全体をクラッシュさせるのを防ぎます。これは、家庭にあるブレーカーと同じ仕組みです。
サーキットブレーカーには3つの状態があります:
- CLOSED: すべてが正常に動作しています。すべてのリクエストが通過します。システムは失敗を追跡します。失敗が制限に達すると、回路が開きます。
- OPEN: システムは即座にすべてのリクエストを停止します。これにより、障害が発生しているサービスが回復するための時間が確保されます。
- HALF_OPEN: システムは少数のテストリクエストを許可します。それらが成功すれば回路は閉じ、失敗すれば再び回路が開きます。
以下は、コードによる簡単な実装例です:
export class CircuitBreaker {
constructor(failureThreshold, cooldownMs) {
this.failureThreshold = failureThreshold
this.cooldownMs = cooldownMs
this.state = "CLOSED"
this.failureCount = 0
this.lastFailureTime = null
}
openCircuit() {
this.state = "OPEN"
this.lastFailureTime = Date.now()
}
closeCircuit() {
this.state = "CLOSED"
this.failureCount = 0
this.lastFailureTime = null
}
halfOpenCircuit() {
this.state = "HALF_OPEN"
}
async execute(fn) {
if (this.state === "OPEN") {
const cooldownExpired = Date.now() - this.lastFailureTime >= this.cooldownMs
if (!cooldownExpired) {
throw new Error("Circuit is open.")
}
this.halfOpenCircuit();
}
try {
const result = await fn()
if (this.state === "HALF_OPEN") {
this.closeCircuit()
}
return result;
} catch (error) {
if (this.state === "HALF_OPEN") {
this.openCircuit()
throw error;
}
this.failureCount++
if (this.failureCount >= this.failureThreshold) {
this.openCircuit()
}
throw error
}
}
}
この仕組みによって、最近の問題は解決しました。エラーの氾濫によってアプリケーションが停止してしまうのを防いでくれます。
ぜひコメント欄で感想を聞かせてください。私はまだ勉強中です。
出典: https://dev.to/neel-vekariya/circuit-breaker-explained-through-real-failure-experience-3aeg