AWSクラウドネイティブデザインパターン 読書メモ

はじめに
クラウドネイティブを実現する要素の1つとして、疎結合な性質がある。
コントロール可能なサービスが明確に定義されたインターフェイスによって連携するのが疎結合なアーキテクチャである。
コントロール可能とは望む動作や望む結果が得られるように統制されている状態であること。
↓自分で解釈した例
①巨大なモノリスアプリケーションでも適切にモジュール化が行われ自動テストがあるならばコントロール可能
②コンテナでもイメージがミュータブルに扱われており自動テストがなければコントロール不可能
③仮想マシンにFTPでファイルをアップロードされると処理されるシステムでもOSからソフトウェアまですべてパラメーターが管理され適時更新されており自動テストがあればコントロール可能
コンテナ、サーバーレスは疎結合を実現するために有用なアプローチではあるが、疎結合を保証するものではない。

第1章
サービスごとの責任共有モデルを意識してなるべく、クラウド利用者の責任が少なくできるサービスを利用することが好ましいという話。
クラウド利用者側の責任だとしても、監視とアラートのCloudWatchなどフォローするサービスはあるので全部を利用者で作る必要があるわけではない。
クラウド利用者の責任が少ないサービスほど対応するワークロードは限定的になる、例えばLambdaは1リクエストに対して1つのインスタンスが立ち上がる、常時起動して多数のリクエストを受けるアプリケーションの場合はApp Runnerのほうがマッチする場合がある。

第2章
迅速かつ頻繁なデプロイを実現するためには十分な自動テストが必要である。
意味があるテストのためにはテストの信頼性が大切である。
QAチームなどによるテストは実装からフィードバックまでが遅いので、思い出しながら調査と対応が必要になるパフォーマンス向上に寄与しない。迅速にフィードバックができるユニットテストを拡充されるべきである。具体的にはテスト全体の70%がユニットテストであるべき。
テスト容易性を高めるアーキテクチャパターン
- 依存関係の逆転
- コンテナによる依存関係の注入
- Docker ComposeでMySQLやRedisを立ち上げる
- コマンドとクエリの分離
- Createのメソッドで値を返却しない、副作用があるメソッドはレスポンスをvoidにし、Readのメソッドは別に定義する。 → ※RESTfulなリソース作成の思想には反するのが気になった。
- コマンドとクエリの責任分離
- 複数のエンティティにまたがるレスポンスを返却する際に、それぞれのエンティティを復元するのではなく、直接クエリをサービス層で書いてレスポンスする

第3章
継続的インテグレーション
トランクベース開発、1つのブランチだけを長期維持し(大抵はmainブランチ)他のブランチは短期でマージしていくスタイルがオススメされている。
長期維持されるブランチが増えると①リリースの安全性が損なわれる ②リファクタリングが難しくなり、技術的負債が積み上がる
継続的インテグレーションのためには以下のプラクティスが必要である。
-
信頼できる高速な自動テスト
- テストを常に回し、エラーが出たら即座に開発を止めて修正を行う
-
小さいチャンクでの機能開発
- INVEST: Independent, Negotiable, Valuable, Estimable, Small, Testableな粒度でブランチを切り開発ができたらmainにマージする ※ValuableとSmallが反するときがあるので悩む、例えばSMS認証機能をリリースしたい場合には、①電話番号登録 ②電話番号検証 ③SMS認証のように細分化できるValuableで考えるとこれら3つはまとめるべきだが、Smallで考えると3つに分けたい。自分なら3つに分ける。
-
デプロイとリリースの分離
- 上記を行うと機能のリリースが自動的に行われる、これが好ましくない場合があるので後述のContinuous Configuration(Featureフラグ)を使う。
Featureフラグを使うことで常に機能が追加されてもDev/Stg/Prod環境ごとに機能の有効化、つまりリリースを制御できる。
リリースに数週間単位で手動テストが必要になる場合はリリースブランチを作成し、そのブランチに対してテストを行う。このブランチで修正が必要になった場合はそれをmainブランチにCherry Pickする。これによりリリースブランチからmainブランチへのマージが行われないので長命ブランチの問題を回避できる。