2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
サーキットブレーカー関連について(全1記事)
リンクをコピー
記事をブックマーク
廣部圭一氏(以下、廣部):自己紹介します。私はKyashに2019年の5月に入社しました。ふだんはFundsチームという外部のベンダーとのやり取りを主に行うチームを担当していて、クレジットカードのチャージ処理や、資金移動ライセンスを下に銀行との接続やATMとの連携を担当しています。個人的に興味があることは、データベースの実装です。
さっそくCircuit Breakerについて話します。まずは、「そもそもCircuit Breakerとは何なのか」というところを話したいと思います。資料の右側に映っているのは『マイクロサービスアーキテクチャ』という本で、11.5章にマイクロサービスにおけるサービス全体への障害の影響を最小限にする方法が紹介されていて、方法が大きく3つ紹介されています。
1つ目はタイムアウトで、一番基本的なものになるんですが、タイムアウトを設定することによって、プロセスが滞留する可能性を減らすことができます。呼び出し先のサービスが負荷などで一時的にサービスが止まっているというときに、クライアント側がプロセスが滞留する可能性を減らすことができます。
基本的には7秒から9秒でタイムアウトを指定していることが多いんですけど、Fundsチームの場合は、特に外部ベンダーとやり取りをすることが多いので、それらのAPIを叩くときには必ず指定をするようにしています。ただ、外部ベンダーのAPIの仕様書で「タイムアウトは必ず1分以上でないといけない」ということもあって、その場合はタイムアウトを設定することの効果がほぼなくなってしまいます。
次に隔壁というものです。これは概念的なもので、被害を最小限にするためのサービス間に壁を設けるような仕組みや設定などを指しています。右側にある図は本に記載されている図で、あくまで隔壁の1つの例ですが、呼び出し先によって接続のプールを分けることで、2つのサービスがあって片方のサービスが重くなった場合に、片方の接続プールが影響を受けないための仕組みが載っています。
KyashはGoを使っているんですけど、Goの場合はnet/httpのMaxIdleConnsPerHostの設定で同じようなことができると思います。
最後が今回のテーマのCircuit Breakerです。これはまさに自宅のブレーカーと同じ仕組みです。右側の図にあるように呼び出しがタイムアウトしたり遅くなってきたりするのを判定して、ある閾(しきい)値を超えるとリクエストをさせないようにするという仕組みで、ブレーカーが落ちる流れと同じです。
システムが自動で復旧していくのが理想的な流れですが、健全性をチェックして、サービスを呼ぶことができると判断をしたうえで再開という流れです。この3と4のプロセスは常にできるとは限りませんが、したほうがよいものではあります。
KyashにはもともとCircuit Breakerの仕組み自体はあって、cronで数分ごとにjobを起動して、New Relicという監視ツールのレスポンスタイムの90パーセンタイルといった特定のメトリクスを参照して、その閾値を見て判断するというものがありました。
具体的には、健全性のチェックの結果をRedisに保存し、リクエストすべきかどうかを判断するという流れです。
監視ツールをDatadog Monitorに移行するときに、もともとこういう構成にしようという話になっていて、jobでポーリングするんじゃなくて、SNSに通知してSNSからLambdaを。それで、Lambda内で先ほどのRedisに書き込む処理をするという流れを想定していました。
この移行自体がすでに進んでいたタイミングで私が対応することになって、メンテナンスをしていくのが辛そうだなと感じました。今後もFundsチームでは、外部のベンダーと接続していくし、Circuit Breakerも継続的に必要だからそれを考えるとちょっと辛そうだなと。
例えば新規のCircuit Breakerを作りたいときは、Datadog MonitorとSNSとLambdaの3つのセットが必要になります。これを都度作っていくのは大変そうだなと思います。かと言って、1つのLambda関数にどんどん処理を追加していくとLambdaに割り当てるAWSの権限等が肥大化し、各マイクロサービスのドメイン知識がLambdaに入り乱れる状況になったりします。
そこで私は、汎用的な仕組みを作りました。具体的には、Datadog MonitorからSNS、Lambdaという流れはそのまま踏襲して以下を満たしたいと考えました。
各マイクロサービスに具体的な処理をさせて、Lambdaは各マイクロサービスのREST APIのエンドポイントを叩くだけにしたいので、この場合、Lambdaはどこをどうやって叩けばいいのか判断をする必要があります。
他にもイベントに付随する情報をどうやって取得するべきかという問題があります。例えば銀行のチャージの場合は、どの銀行のレスポンスが遅いのか、障害に近いのかという情報が必要なので、銀行コードというものが必要です。
ただ、その処理をLambdaに書いてしまうと、汎用的にしたいという目的が達成されなくなってしまいます。また、右にスクリーンショットを貼っているとおり、Datadog Monitorにはいろいろなmonitor typeがあるので、汎用的に作るのであればそのすべてに対応できるようにする、というのが満たしたいことでした。
まずどこを叩けばいいのかをどうやって知るかというと、Datadogの設定のところにこういったかたちで書きます。通知先はここにあるように1つはSlackのチャンネルで、もう1つはSNSですね。SNSとSlackに通知します。if文でアラートを書けるので、サービスで叩いてほしいエンドポイントをここで指定することで達成できます。
次に、イベントに付随する情報をどうやって取得するべきか。またあらゆるmonitor typeにどうやって対応するべきかですが、どうやって達成できるかを考えるのにかなり時間がかかりました。調べてみたら、DatadogはREST APIを提供していることがわかりました。CURLだとこんな感じです。5言語ぐらいのライブラリがすでに用意されていて、Goもあるのでこんな感じでかなり簡単に書けます。
まず何をもとにREST APIを叩くかというと、SNSのメッセージにデフォルトで含まれているevent_idとmonitor_idというものがあります。ここにLambdaが受け取ったSNSのメッセージのログを載せているんですけど、event_idはこの部分に書いています。monitorもどういうmonitorかという情報が公開されています。これをもとにDatadogのREST APIを叩きます。
次に何を取得できるかというと、対象の銀行コードや、イベントが起きた時刻や今起きたイベントは何か、warnなのかalertなのかという情報が取得できます。WebUIにはかなりの情報があるんですが、基本的にすべてREST APIから取得が可能です。
結果的にこうなりました。SNSとLambdaは1つずつ存在する。Datadog Monitorは監視したい項目ごとに作って通知先として登録します。Lambdaが指定されたコールバックを叩いて、各サービス(ECSやFargate)がevent_idやmonitor_idをもとに詳細を取得して、各自でRedisに書いたりデータベースに書いたりという処理をします。
Lambdaは何をするのかをもう少し詳しく話すと、event_idとmonitor_idを判別します。そして、circuit-breaker-callbackが指定されていれば叩きます。レスポンスステータスコードだけを見て200だと成功、200以外であればエラーとして、エラーが起きてもLambdaの関数内でエラーを投げるようにしています。Slack通知などは別の仕組みでしていて、こちらはあとで説明します。
Lambdaは再送の処理がデフォルトで組み込まれているので、再送を勝手にしてくれます。またデッドレターキューも設定できるので、再送上限で失敗した場合にデッドレターキューに勝手に入るという仕組みにもできます。Slack通知もデッドレターキューをDatadog Monitorで監視するという仕組みで達成できます。
Kyashではこれ以外でも、基本的にデッドレターキューはDatadog Monitorで監視してすぐに気づくようにしています。
結局何がうれしいのかというと、Lambdaの改修は1度作ってしまえば基本不要ということです。やることは単純でパースして叩く。レスポンスステータスコードを判断するというだけなので、改修は一切不要です。インフラ的に必要な要件がLambdaから各サービスへネットワークの到達性なので、基本的にSREの裁量はまったく発生しません。すでにあるコード資源、ドメイン知識などが利用できます。
最後にまとめです。作ったのはいいんですが、アラートやリカバリーの閾値の決めというのがすごく難しくて、最初はSlack通知をもとにどの辺りがいいのかを話すことになると思います。これはよくよく考えると、Datadog Monitorのイベントを各マイクロサービスにハンドリングする仕組みなので、Circuit Breaker以外の用途にも使えそうだなと思いました。
話しきれない部分も多かったので、興味がある方はアドベントカレンダーを参照していただければと思います。以上です。ご清聴ありがとうございました。
関連タグ:
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05