サービスメッシュは本当に必要なのか、何を解決するのか
1つのアプリケーションからサービスメッシュに至るまでに起こる課題とその解決方法
LB -> App -> DB のシンプルな構成
App が大きくなる
本番環境でうまく動かないことがあるとか、ダウンタイムが発生するとか、障害が起こるようになる
→マイクロサービス化しよう!
Monolith という呼称に混められるニュアンス・課題感
関係者感調整のオーバーヘッド
変更による影響範囲の広さ
モジュール構造維持の難しさ
非効率なスケーリング
いろんな機能の中のある1機能がすごくリクエストが多いと、この機能だけスケールアウトしたいのに他の使われない機能もスケールアウトしないといけない
テスト・ビルドに要する時間の長さ
小さい変更ごとにデプロイするモチベーションが下がる
マイクロサービス化に期待される効果
変更による影響範囲の局所化
機能単位で分割される
e.g. カートのシステムと商品一覧のシステムが別物になる
モジュール境界の維持しやすさ
独立したデプロイとスケーリング
自立的なチームによる開発・運用
多言語を使える
マイクロサービスアーキテクチャが多言語を利用することを要請しているわけではない
モノリスの考察
ALB -> App on EC2/Container -> Aurora
現実世界のモノリスは複雑
実際には複数インスタンス構成とかS3とかSQSとかElastiCacheとか使ってるよね
ストーリー
ある日、たまにリクエストがすごい遅いことがある
POST /something に対するレスポンスが 2000 ms だ!
ALB -1> S3 にファイル書き出し -2> SQS に積む -3> 処理 -4> レスポンス
どこに時間がかかった?
AWS X-Ray
分散アプリケーションの分析と調査ができる(分散トレーシング)
これを導入していれば、モノリシックであっても調査は結構簡単なはず
マイクロサービス
成熟したマイクロサービスがどうなるか?
ひえ〜〜〜〜〜〜〜〜って感じのネットワーク図
マイクロサービスの課題
サービスの適切な分割
先程、カートと商品一覧のサービスを例にしたが、これが良いのかわからない
サービスの分割には正解がない
DDD とかのプラクティスはあるものの……
チームの状況とかも影響する
テストの難しさ
モノリシックでもインテグレーションテストは大変だが、マイクロサービスですべてのサービス・コンポーネントを揃えたインテグレーションテストはだいぶ大変
影響範囲を自サービス内に収める難しさ
他のサービスに呼ばれている以上、後方互換性を簡単に切れhれない
サービス感通信の信頼性 Reliability
掘り下げる
サービス感通信の可観測性 Observability
掘り下げる
Reliability
マイクロサービスは一種の分散システム
ネットワーク経由通信なので、失敗が前提
一時的なネットワーク状況による失敗
対抗サービスの不具合・停止にyる失敗
→防御的実装が必要(分散システムなので)
防御的実装の例
呼び出し先サービスの位置は一定ではない
→サービスディスカバリ
一時的な呼び出しの失敗
→リトライ
しかも、サービスディスカバリからやり直す必要がある可能性もある
継続した呼び出しの失敗
→サーキットブレーカー
何度呼んでも失敗するなら、直るまで一旦ペンドすべき
呼び出し先サービスのパフォーマンス悪化
→タイムアウト
呼び出し元システムの不具合
→スロットリング
ずっと400を返すしかないリクエストばっかり送ってくるやつがいたら、そいつを一旦ブロックする
Observability
あるとき、ユーザーにエラーが返ったとする
マイクロサービス群はユーザーから見ると1つのシステム
なので、失敗はシステムの失敗
この失敗はどこで、何故起きたのか把握する必要がある
そもそも観測できる必要がある
サービス感通信の可観測性を高める実装
ログ/メトリクス/トレース情報出力
結構出してることがある
各サービスの既存実装の出力フォーマットが不揃いだとコンテキストが見えない
これは、システム全体の観測には不向き
→ 全サービスの出力フォーマットを統一する必要がある
これが可能か?
すべてを実装しきることは可能なのか?
各サービスへの個別実装
複数の言語やフレームワーク
実装担当者と品質担保方法
統一フォーマットの変更
変更があったら全サービスで変更する必要性がある
→一貫性のある実現方法が必要
一貫性あるサービス感通信の信頼性/加速性実装
共通ライブラリという解決策
起きうる問題
アプリケーション側
アプリケーション改修が必要じゃん……となりがち
共通ライブラリによるパフォーマンス悪化
言語のバージョンアップに対応できない、ある言語に対応していない
ライブラリ側
あるアプリケーションが入れてくれない
移行してくれない
この言語書いたことない
そもそも、マイクロサービスは疎結合な仕組みが成功の秘訣
共通ライブラリは密結合を生んでしまう
プロキシへのオフロードというアイデア
プロキシ(サービスの通信が全てここを通じて行われる)でReliability, Obserbability を担保する
プロキシのデファクトになってる
設定方法
yaml を書いて突っ込む
問題
proxy と application はセットに動かなければいけないので、開発と運用にハレーションが発生
AWS App Mesh
サービスメッシュのマネージドコントロールプレーン
うれしさ
アプリケーションは勝手にやってくれれば良い
Envoy のデプロイは AWS App Mesh から動的にできる
強み
アプリケーションレベルのネットワーク
クラスタやサービスにまたがるメッシュの構築
トラフィック管理
トラフィックコントロール
サービスディスカバリとか
ルーティング
Observability
ロギング・メトリクス・分散トレーシング
Tokyo Region で使える、料金は発生しない
ロードマップが GitHub で公開されてる
あなたのシステムにとってサービスメッシュは本当に必要なのか?
課題に対する必要性を検討する
サービスメッシュは必要?
X-Ray の分散トレーシングで十分な場合もある
ALB でのトラフィックコントロールで十分な場合もある
OSS による共通ライブラリの利用で十分低コストな場合もある
動的なサービスメッシュは必要?
Envoy に直接静的設定ファイルを載せるのでも良い場合もある