Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

AWS Lambdaを使ってシステム監視を強化してみた@ServelessMeetup#5

kabutoya
September 11, 2017

AWS Lambdaを使ってシステム監視を強化してみた@ServelessMeetup#5

AWS LambdaとTwillio APIを利用してシステム監視に電話通知機能を追加した話

kabutoya

September 11, 2017
Tweet

Other Decks in Technology

Transcript

  1. ⾃⼰紹介: 甲⾕ 悠(カブトヤ ユウ) • 所属: リクルートテクノロジーズ • テクノロジプラットフォーム部 •

    リクルートが持つ様々なメディアの運⽤改善を実施 • 直近だとPythonを利⽤した構成管理を推進中 • 早くPython使いになりたい。。。 • 趣味: マラソンやってます • 東京マラソンは3回⾛った(⾃⼰ベスト4:35) • 来年は当たるのか。。。 2
  2. システム監視強化の背景(2/3) • しかしメール通知のみでは対応が遅れ被害が拡⼤する。 • ⼤規模サービスだと1分間に1万以上のリクエストが発⽣する。 • DB障害といったサービス全体に影響がある障害の場合、被害が甚⼤に。 • そこで、メールに加えて電話連絡を実現することにした。 •

    Twillio APIからのCallBackへXMLを返すことで電話メッセージを動的に作れる。 • Twillio APIは電話からのプッシュ通知にもとづいて次のアクションを変更できる。 AWS(監視アカウント) 執務環境 サイト 担当 サービス稼働中のインフラ サービスA サービスB Web zabbix-agent td-agent ... Batch zabbix-agent td-agent - - - - サイト 担当 通知 DB zabbix-agent td-agent etc zabbix-agent td-agent 通知 SaaS(Twilio) 通知 API連携 6
  3. システム監視強化の背景(3/3) • (当時の)Twillio APIでは標準で以下の機能を実現することができなかった。 • 担当者が電話をフックできなかった場合の輪番制御。 • 発⽣したホスト名や障害ポイントを通知内容へ動的バインド。(実現できるがURLの可読性が激減する。) • そこでAPI

    Gateway + AWS LambdaによるTwillio連携を実施。 • 監視通知のためにサーバ増やすのも本末転倒。 AWS(監視アカウント) 執務環境 サイト 担当 サービス稼働中のインフラ サービスA サービスB Web zabbix-agent td-agent ... Batch zabbix-agent td-agent - - - - サイト 担当 通知 DB zabbix-agent td-agent etc zabbix-agent td-agent 通知 SaaS(Twilio) 通知 API連携 ここにAPI Gateway+AWS Lambdaを採⽤ 7
  4. Twillio API連携 - API Gateway(1/2) • API GatewayはLambdaへの認証とrequest/responseの マッピングを実施している。 •

    認証には呼び出し元(ZabbixとEFK)にAPI Keyを払い出す簡易認証を採⽤。 • あわせてスロットリング/クォータ制限を各呼び出し元に設定しリクエストを調整。 • request/responseのマッピングにはtemplateを活⽤。 • request: パスパラメータ&URLパラメータ→JSON変換にてLamdaが利⽤。 • response: JSON→XML返還にてTwillioAPIが利⽤。(Velocity形式で出⼒内容を制御) これがTwimlの形 @Velocity 9
  5. Twillio API連携 - API Gateway(2/2) • API Gatewayは2つのLambdaそれぞれに向けたURLを公開。 • ①⽤に先述の簡易認証を、②ではVelocityを利⽤したXML整形を⾏っている。

    対象 URL URLパラメータ Lambda① /phonecall/{groupId} messageId : Twillioが話す内容 variableMessage : 話す内容の中の置換⽂字 Lambda② /phonecall/{groupId}/{cont} token : Lambda①が発⾏したElasticache アクセス⽤Token Digits : Twilioからの電話fook結果 この組み合わせで輪番先を制 御している。 10
  6. 補⾜:Twillio APIは • Twillio API呼び出しにてTwiml を返すURLを指定。Twimlの内容に応じ電話内容を制御。 • Twimlは通話内容を記載する<Say>や電話を受けた⼈に操作を促す<Gather>、無応答の場 合に別のURLを呼び出す<Redirect>等のタグを利⽤してメッセージを制御できるXML。 引⽤元

    https://jp.twilio.com/docs/api/twiml • 利⽤料は発信元として利⽤する電話番号(1契約100 円/⽉)と通話料。 • 右記URLではTwillio SDKを利⽤たサンプル(ロジッ クにてTwiml直操作)だが、Velocity等のTemplate エンジンを利⽤したMとV分離の実装のほうが個⼈ 的には責務を分離できてよい。 11
  7. Twillio API連携 - Lambda① • 前⾯のLambdaは利⽤者(≒Zabbix等の監視基盤)に対する エントリポイントとして機能させている。 • API Gatewayのステージ変数によって検証⽤/本番⽤それぞれの固有情報(電

    話先やTwillio APIのクレデンシャル情報)を切り分けてElastiCacheに格納。 • どのグループに対して、どんなメッセージを通知するのかのセットをRDSから取得し、 後述のロジック本体⽤のLambda向けにTokenを⽣成している。 executeQuery(query.monitorGroup, [groupId, now, now] , rows=>{container.group = rows[0];})() .then(executeQuery(query.twilioMessage, [messageId, now, now] , rows=>{container.message = rows[0]; container.message.msg = util.replaceHolder(container.message.msg, msgs)})) .then(executeQuery(query.envInfo, [envType, now, now] , rows=>{ var env={}; for(var i=0; i<rows.length ;i++)env[rows[i].envCode] env = rows[i].envValue; })) 輪番⽤のメッセージ構築@RDSも Promise使えば可読性が上がる。 12
  8. 補⾜:RDS+ElastiCacheを利⽤した理由 • RDSの利⽤は既存運⽤との親和性。 • 既存のシステム運⽤を⾏っているメンバーはRDBMSへの知⾒が⾼かった。 • 新しい技術要素を取り込みすぎると監視基盤⾃体が動かなくなってしまうリスクが。 • ElastiCacheは発⾏されたTokenに有効期限を設けるため。 •

    パフォーマンス要件は⾼くなかったのでキャッシュよりも有効期限の側⾯が強い。 • 監視基盤の通知機能強化というパフォーマンスをあまり求められないシステムだった のでRDS(& ElastiCache)を採⽤。 • VPCアクセスに伴うENI作成(スループット)やRDSとのセッション上限(可⽤性)等の特徴 を踏まえて利⽤判断を⾏うべきです。 既存Zabbixサーバを踏み台にして RDS、ElastiCacheのメンテナンス。 13
  9. 状況に応じてループ回数が変わる機能には再帰処理が最適。再帰処理はAWS Lmbda⾃体を関数 と捉えると⾮常にシンプルに実装できる。 Twillio API連携 - Lambda② (1/2) • 後⾯のLambdaはTwillioに対して電話発信指⽰と発信結果の

    制御をやるメインのロジック。 • Twillio APIは発信結果をCallBack StatusとしてAPI呼び出し元に返してくる。 • Statusから次のメンバー向けに電話発信指⽰をするかの判断は機能⾃体を再 帰的に呼び出すことと相性が良い。 StatusがNGだったらAPI呼び出し。 OKだったら処理終了。 OK/NGの結果は呼び出し 元Lambdaに返す。(リク エストを出す) 14
  10. Twillio API連携 - Lambda② (2/2) • 実際には。。。 • Twillioの電話通知結果のステータスは複数。 •

    受けた • 受けた場合にはGather(電話のプッシュボダンのどれを押したか) • 通話中 • 受け取らない • Lmabda②の実装(条件分岐)は肥⼤化してしまった。 • とはいえ1つのハンドラで100⾏ちょいなので許容範囲(なはず。) 15
  11. 良かったこと - Restful APIへの理解 • API GateWayの管理コンソール。 • API Gatewayの利⽤に限らずRestfulな「APIを決める上で必要なこと」を

    ⾃ずと学びながら構築ができる。 リソース単位でアクションを決め て。 各アクションで必要なHTTPステー タスコード(とレスポンスBody)を 決める。 ステージ(バージョン)を定義 してURLとバインド。 APIとして決めないとダメなことがしっかり表現されているので 忘れない(し抜けてた観点に気づくことができる)。 16
  12. 良かったこと - 構築スピード • 構築までの⽴ち上がりが⾮常に早い。 • ElasticachやRDSとの接続にaws-sdkを利⽤。ドキュメントやサンプルソースもあり、 なによりもAPIが直感的に使えた。 • 2年ほど前、Java向けのS3やDynamo向けのデータ作成実装の研修を受けたときにはな

    かなかひどいAPI (全然fluentじゃないAPI)だった記憶があるのでここが⼀番不安だった。 • API Gatewayとの統合リクエストにてLambda Functionの呼び出しはマッ ピングテンプレートの設定のみであるためほぼ機能の構築のみに集中できる。 17
  13. 良かったこと - コスト • 追加コストがとても少ないので起案時にもメリットを伝えやすい。 • (実際にはそんなに発⽣しませんが)1⽇100件の電話連絡を⾏った場合でも 6500円以下。 サービス 利⽤量

    コスト(⽉) API Gateway 3MB 0.1円未満 6410円/⽉で 運⽤ AWS Lambda 15,000秒 無料 RDS (db.t2.micro) 2台構成 1,330円 ElastiCache (cache.t2.medium) 2台構成 1,330円 Twilio API 15,000秒 3,750円 1ドル110円で計算 • やってみよう!という機運を醸成しやすい。 • 運⽤開始までのスピードも上がる。 18
  14. 反省すべきこと - CI/CD • 実装から公開までのリリースにてCI/CDの仕組みを組み込めなかった。 • そもそもAWS Lambdaに対するCI/CDのGood practiceが⾒いだせず。。。 •

    テストティングフレームワークの組み込み。 • API GatewayのStagingとLambda連動。 公開 (リリース) ステージング デプロイ 単体テスト 実装 • 最適なテスティングフレーム ワークは? • 外部サービスのモックをライト に作るには? • Lambda Functionデプロイの タスクランナーは? • 作成したアーカイブの(ラン ナー経由での)publish⽅法は? • API Gatewayのステージとデプ ロイしたLambda Functionの 紐付けは? 20
  15. 反省すべきこと - X as a Code • LambdaだけでなくAPI Gatewayのコード化/デプロイが実現できなかった。 •

    Serverless Frameworkを利⽤してAPI Gateway+Lambdaのコード管理を検討した。 • 社内インフラとAWSの接続の関係上NW周りの操作を⾏うポリシーは個別に 適⽤する⽅針。 • そのためServerless Frameworkが必要としているポリシーに対応していくのに 時間がかかり断念。 • ⼈柱になって必要な権限を確⽴しておき、今後の利⽤の知⾒をためておくべきだった。 • 現状ではSwagger定義をLambda Functionとともにリポジトリ管理するにとどめて いる。 21
  16. 反省点を解消し、デプロイ作業の⾃動化を実現。 ① git commit • Unitテストの実⾏ • 構⽂チェック/カバレッジレポート⽣成 ② (Testが通れば)Lambdaへのデプロイ

    • API Gatewayステージング環境との紐付け ③ API callのテスト/公開 • テストを踏まえた本番環境へのデプロイ • 必要に応じてAPI Gatewayのリソースバージョンの更新 今後の展望(未定) - CI/CDの実現 • テスティングフレームワークを導⼊し、CI/CDの実現。 • コンソール上でのバージョン管理の実現。 公開 (リリース) ステージング デプロイ 単体テスト 実装 22
  17. 今後の展望(未定) - 監視+復旧 • 今は特定閾値に応じたアラート通知のみ。 • 通知内容と復旧⼿順が確⽴されたソフトウェアに対して復旧までを実現。 • 所定のログ回収(アクセスログやメモリダンプ等) •

    所定の復旧⼿順(再起動や切り離し) AWS(監視アカウント) 執務環境 サイト 担当 サービス稼働中のインフラ サービスA サービスB Web zabbix-agent td-agent ... Batch zabbix-agent td-agent - - - - サイト 担当 通知 DB zabbix-agent td-agent etc zabbix-agent td-agent 通知 SaaS(Twilio) 通知 24 ⾃動復旧 • Ansible等のプロビジョニングツールを起動して 復旧処理を実施。 • まずはAWS(VPC)上の各サーバに対して復旧処理 を実施するほうが現実的かも。