下流サービスの機能不全
各サービスは接続する下流サービスが止まった場合、または機能低下を起こした場合、どういった振る舞いをするかを常に考えておく。
タイムアウトを設けて、一定時間以上応答がない場合は例外処理をするのが一般的だけど、タイムアウトが長すぎたりすると処理しきれないリクエストが溜まりすぎて健全なサービスまで影響及ぼす可能性もあるので注意。
サーキットブレーカー
下流サービスの状態を問い合わせするサービスが持っており、問い合わせ失敗時に状態を更新する。下流サービスの状態がfail時には、クライアントからのリクエスト時には下流サービスに接続することなく、例外処理を行えば良い。
failからpassへの切り替えは、一定の間隔でポーリング等して死活確認すればよい。という考え方。
スケーリング
重要度による業務の分割
クリティカルなサービスほど、その業務だけに集中させるような設計にしたい。
例えば、顧客の購買取引処理と1日に1度の売り上げ集計を同サービス上で設計しない。など。
データベース書き込みのスケーリング
Readのスケールアウトはレプリケーションで容易にできるんだけど、書き込みの場合はシャーディングでスケールする。
最近のRDBはパーテーション機能が標準で備わってるが、複数ノードでシャーディングしたい場合はそれ用のデータストアを利用したほうが楽そう。
また、即時を求めるような書き込みでない場合、書き込みをバッファリングやキューイングして非同期で書き込むなんていうのもあり。即時性は求めないが原子性を求めたい場合とかは、非同期でストアドを叩くなんて手もある。また書き込み対象の下流サービスが障害起こした場合、復旧後にバッファできる量まではデータを再現できるなどの効果もある。
キャッシング
キャッシュには応答を早くする効果の他にも、可用性を向上させる効果もあるということを覚えておく。
下流サービス障害時にキャッシュを返すことで、クライアントにはサービスを提供できることになる。エンドツーエンドの監視を行っている場合などには障害検知に時間がかかってしまうので、ミクロの単位で監視するよう心がける。
サービスの性質を検討して厳密な鮮度を提供しなくて良い場合、キャッシュを積極的に利用しよう。
また、"キャッシュ切れ"を起こした場合、オリジンサーバへアクセスが集中する場合があるので、そのリスクと回避を見積もっておく。
CAP定理
複数ノードにデータを配置しているという前提で、各サービスの性質に応じて一貫性か可用性どちらを取るかを検討する。
新しくデプロイされたノードを管理する
当然、サービス全体でアドレスを共有しないといけないんだけど、都度インターナルDNSを登録して、ロードバランサに追加〜とか、ノードを破棄した時は〜、リードレプリカを追加した時は〜、なんかの作業を体系化したい。
最後に
これで一通り読み終えたんだけど、amazonのレビューでもある通り、翻訳がすっと頭に入ってこずに何度か読み直してようやくどんなことを言っているか理解するようなことがあった。読みやすい読みづらいでいうと自分的には読みづらい部類に入ると思う。
あくまで考え方を説いているのが大半で設計以前とまではいかないまでも、具体的な操作について触れていることは少ないかな。何かお題があってチュートリアル的にマイクロサービス化していきましょうといったものではないので、読み終えてもDockerでコンテナマイクロサービスを自動でデプロイだー。ってできるようにはならないはず。
マイクロサービスだとこういう考え方で、こういった課題解決(特に分断耐性とデプロイ運用)に向いているけど、ここは注意なー。みたいなマイクロサービスの主旨は把握できる本だと思う。