2024.12.10
“放置系”なのにサイバー攻撃を監視・検知、「統合ログ管理ツール」とは 最先端のログ管理体制を実現する方法
サーキットブレーカー関連について(全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.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
2024.12.09
10点満点中7点の部下に言うべきこと 部下を育成できない上司の特徴トップ5
2024.12.09
国内の有名ホテルでは、マグロ丼がなんと1杯「24,000円」 「良いものをより安く」を追いすぎた日本にとって値上げが重要な理由
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.12.10
職場であえて「不機嫌」を出したほうがいいタイプ NOと言えない人のための人間関係をラクにするヒント
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.06
嫌いな相手の行動が気になって仕方ない… 臨床心理士が教える、人間関係のストレスを軽くする知恵
PR | 2024.11.26
なぜ電話営業はなくならない?その要因は「属人化」 通話内容をデータ化するZoomのクラウドサービス活用術
2024.12.11
大企業への転職前に感じた、「なんか違うかも」の違和感の正体 「親が喜ぶ」「モテそう」ではない、自分の判断基準を持つカギ
PR | 2024.11.22
「闇雲なAI導入」から脱却せよ Zoom・パーソル・THE GUILD幹部が語る、従業員と顧客体験を高めるAI戦略の要諦