2024.10.21
お互い疑心暗鬼になりがちな、経営企画と事業部の壁 組織に「分断」が生まれる要因と打開策
サーキットブレーカー関連について(全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.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.21
40代〜50代の管理職が「部下を承認する」のに苦戦するわけ 職場での「傷つき」をこじらせた世代に必要なこと
2024.11.20
成果が目立つ「攻めのタイプ」ばかり採用しがちな職場 「優秀な人材」を求める人がスルーしているもの
2024.11.20
「元エースの管理職」が若手営業を育てる時に陥りがちな罠 順調なチーム・苦戦するチームの違いから見る、育成のポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.19
がんばっているのに伸び悩む営業・成果を出す営業の違い 『無敗営業』著者が教える、つい陥りがちな「思い込み」の罠
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは