What is Circuit Breaker?
あるアプリAが外部サービスであるアプリXと連携している際、アプリXがサービスダウンした場合に他サービスへ影響を出さないよう制御する仕組み。
状態遷移
使用するデモ
やってみる
health check
(backendA
のステータスが"state": "CLOSED"
になっていることが確認できる。)
curl http://localhost:9080/actuator/health | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 609 100 609 0 0 9755 0 --:--:-- --:--:-- --:--:-- 10684
{
"status": "UP",
"components": {
"circuitBreakers": {
"status": "UP",
"details": {
"backendB": {
"status": "UP",
"details": {
"failureRate": "-1.0%",
"failureRateThreshold": "50.0%",
"slowCallRate": "-1.0%",
"slowCallRateThreshold": "100.0%",
"bufferedCalls": 0,
"slowCalls": 0,
"slowFailedCalls": 0,
"failedCalls": 0,
"notPermittedCalls": 0,
"state": "CLOSED"
}
},
"backendA": {
"status": "UP",
"details": {
"failureRate": "-1.0%",
"failureRateThreshold": "50.0%",
"slowCallRate": "-1.0%",
"slowCallRateThreshold": "100.0%",
"bufferedCalls": 0,
"slowCalls": 0,
"slowFailedCalls": 0,
"failedCalls": 0,
"notPermittedCalls": 0,
"state": "CLOSED"
}
}
}
},
"ping": {
"status": "UP"
}
}
}
二回失敗させる
curl http://localhost:9080/backendA/failure | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 168 100 168 0 0 389 0 --:--:-- --:--:-- --:--:-- 395
{
"timestamp": "2023-01-02T01:23:12.760+00:00",
"path": "/backendA/failure",
"status": 500,
"error": "Internal Server Error",
"requestId": "2c384fce-3"
}
curl http://localhost:9080/backendA/failure | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 168 100 168 0 0 469 0 --:--:-- --:--:-- --:--:-- 478
{
"timestamp": "2023-01-02T01:23:37.328+00:00",
"path": "/backendA/failure",
"status": 500,
"error": "Internal Server Error",
"requestId": "7868a5ee-4"
}
再度health check
(backendA
のステータスが"status": "state": "OPEN"
になっていることが確認できる。)
curl http://localhost:9080/actuator/health | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 617 100 617 0 0 21606 0 --:--:-- --:--:-- --:--:-- 28045
{
"status": "UP",
"components": {
"circuitBreakers": {
"status": "UP",
"details": {
"backendB": {
"status": "UP",
"details": {
"failureRate": "-1.0%",
"failureRateThreshold": "50.0%",
"slowCallRate": "-1.0%",
"slowCallRateThreshold": "100.0%",
"bufferedCalls": 0,
"slowCalls": 0,
"slowFailedCalls": 0,
"failedCalls": 0,
"notPermittedCalls": 0,
"state": "CLOSED"
}
},
"backendA": {
"status": "CIRCUIT_OPEN",
"details": {
"failureRate": "100.0%",
"failureRateThreshold": "50.0%",
"slowCallRate": "0.0%",
"slowCallRateThreshold": "100.0%",
"bufferedCalls": 5,
"slowCalls": 0,
"slowFailedCalls": 0,
"failedCalls": 5,
"notPermittedCalls": 1,
"state": "OPEN"
}
}
}
},
"ping": {
"status": "UP"
}
}
}
5秒経つと自動でHALF_OPENに移行する
curl http://localhost:9080/actuator/health | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 627 100 627 0 0 20009 0 --:--:-- --:--:-- --:--:-- 25080
{
"status": "UP",
"components": {
"circuitBreakers": {
"status": "UP",
"details": {
"backendB": {
"status": "UP",
"details": {
"failureRate": "-1.0%",
"failureRateThreshold": "50.0%",
"slowCallRate": "-1.0%",
"slowCallRateThreshold": "100.0%",
"bufferedCalls": 0,
"slowCalls": 0,
"slowFailedCalls": 0,
"failedCalls": 0,
"notPermittedCalls": 0,
"state": "CLOSED"
}
},
"backendA": {
"status": "CIRCUIT_HALF_OPEN",
"details": {
"failureRate": "-1.0%",
"failureRateThreshold": "50.0%",
"slowCallRate": "-1.0%",
"slowCallRateThreshold": "100.0%",
"bufferedCalls": 2,
"slowCalls": 0,
"slowFailedCalls": 0,
"failedCalls": 0,
"notPermittedCalls": 0,
"state": "HALF_OPEN"
}
}
}
},
"ping": {
"status": "UP"
}
}
}
ブラウザからhttp://localhost:9080/backendA/successにアクセスして成功リクエストを溜めるとCLOSEDに戻る。
参考