こう 聞かれます
- 「1 つの
サービスの 遅れが 全体に 広がるのを、 どう 防ぎますか」 - 「おすすめの
表示の サービスが 遅くなっただけで、 サイト全体が 開かなくなりました。 なぜですか」 - 「サーキットブレーカーとは
何ですか。 どんな ときに 使いますか」
面接官が 見ている点
- 遅い
相手を 待つ間に、 自分の 接続や 処理の 枠が 埋まって 広がる、という 仕組みを 説明できるか - タイムアウト、
サーキットブレーカー、 枠を 分ける、 早めに 断る、 代わりの 表示、の 複数の 手を 持っているか - 止まっても
よい 機能と、 守るべき機能を 分けて 考えているか - ヘルスチェックや
再試行が、 かえって 広げる 側に 回る ことを 知っているか
短い答え
- 遅い
相手を 待つ間、 自分の 接続や 処理の 枠を 握ったままに なり、 それが 埋まると 関係の 無いリクエストまで 止まる、というのが 広がる 仕組みです。 - だから、
タイムアウトで 待ちを 切り、 失敗が 続く 相手は 呼ぶのを 一時止め (サーキットブレーカー)、 相手ごとに 使える 枠を 分けて、 1 つの 遅れが ほかを 巻き込まないようにします。 - 溢れた
リクエストは 早めに 断り、 止まっても よい 機能は 代わりの 表示に 切り替えて、 守るべき機能 (ログインや 購入など ) を 動かし続けます。
この
少し 詳しい答え
どう広がるか
商品の
さらに、
待ちを 切る、 呼ぶのを止める
まず、
サーキットブレーカーは、
JavaScript
function createBreaker(limit, coolDown) {
let state = "閉";
let failures = 0;
let openedAt = 0;
return function call(time, ok) {
if (state === "開") {
if (time - openedAt < coolDown) {
return time + " 開 呼ばずに代わりの表示";
}
state = "半開";
}
if (ok) {
state = "閉";
failures = 0;
return time + " 呼んで成功 → 閉";
}
failures += 1;
if (state === "半開" || failures >= limit) {
state = "開";
openedAt = time;
failures = 0;
return time + " 呼んで失敗 → 開";
}
return time + " 呼んで失敗 (" + failures + " 回目)";
};
}
const call = createBreaker(3, 3);
const results = [false, false, false, true, true, false, true, true, true, true];
results.forEach((ok, time) => console.log(call(time, ok)));0 呼んで失敗 (1 回目)
1 呼んで失敗 (2 回目)
2 呼んで失敗 → 開
3 開 呼ばずに代わりの表示
4 開 呼ばずに代わりの表示
5 呼んで失敗 → 開
6 開 呼ばずに代わりの表示
7 開 呼ばずに代わりの表示
8 呼んで成功 → 閉
9 呼んで成功 → 閉開いている
枠を 分ける、 早めに断る
- 相手ごとに
枠を分ける 接続の 数や 同時に 走る 処理の 数を、 呼ぶ相手ごとに 分けて おきます。 おすすめの サービス向けの 枠が 埋まっても、 決済向けの 枠は 残ります。 船の 区画を 仕切って、 1 つの 穴で 全体が 沈まないように する 考えで、 バルクヘッドと 呼ばれます - 溢れた
分は 早めに断る 自分が 受けきれない ほどの リクエストが 来たら、 待たせて 全部を 遅く するより、 一部を すぐに 503 で 断る ほうが、 残りを 速く 返せます。 待ち行列にも 長さの 上限を付けます
代わりの 表示で 動き続ける
機能ごとに、
ヘルスチェックにも
トレードオフ
サーキットブレーカーは、
話す例は
よく ある間違い
- すべての
外の 呼び出しが、 同じ 1 つの枠を使う 1 つの 相手の 遅れで、 枠が 全部埋まります。 相手ごとに分けます - ヘルスチェックで
外の 相手まで調べる 相手が 止まると 自分の 全台が 外され、 全体が 止まります - 弱っている
相手に、 すぐ 何度も 再試行する 呼び出しが 増え、 立ち直りを 遅らせます
深掘りの問い
- 「同期で
呼ばず、 非同期に すれば 解決しますか」 結果を すぐ返さなくて よい 処理なら キューに 逃が すのは 有効ですが、 キューが 溜まり 続けるので、 長さの 上限と 監視が 要る、と答えます - 「サーキットブレーカーが
開いた ことに、 どう 気づきますか」 開いた、 閉じたを 記録と 監視に 出し、 開いている 時間が 長い ときは 人を 呼ぶ、 と答えます - 「どの
機能を 守り、 どれを 切るかは 誰が 決めますか」 事業側と 一緒に、 売上や 利用者への 影響で 順番を 決め、 障害の 前に 文書に しておく、と答えます
