kubernetess環境でmicroserviceとsidecarを活用する
背景
1つのマイクロサービスを開発する中で、レガシー環境のCMSにアクセスしてコンテンツを取得する要件が出てきた。
その際に、CMSのresponse形式を指定できず、アプリ側でHTMLをパースしてjsonにする処理が必要になり、その責務をどこに持たせるか?という話
理想
そもそも、理想としてはCMS側がjson形式で返せるように改修するのが理想。
とはいえ、リプレイスが決まっており、かつレガシー環境につき開発コストをそこにかけるのが妥当とは思えないので、他の選択肢を検討している。
パターン① 各MS側に処理を持たせる
愚直に考えたら、これがまず思いつくと思う。
各MS側でCMSにリクエストしたのち、レスポンスの中身をパースする処理を行う。その後、業務ロジックなどを経て、APIレスポンスとして、クライアントに返却するというもの。
至ってシンプルではあるが、下の図のようにAPIが複数存在する場合、MSの数だけ処理が散らばることになり、本当に良いのか疑問が残る。
また、CMSに対してクライアントの責務なのか?というのが、個人的に疑問が残った。
パターン② 共通処理として切り出し、汎用的なサービスを作る
マイクロサービスとして、Parse APIのようなものを作るというもの。
レスポンスヘッダーをみてhtmlだったら、そのままParse APIにMS側からリクエストを送るというもの。
あくまで、これはCMSのリプレイスが終わったら捨てる前提のAPIという建て付けにはなる。
メリットとしては、parseするという共通処理を1つのAPIに集約させることができる。
デメリットとしては、Parse APIが単一障害点になる可能性があり、割と影響度もでかい。また、通信も発生するので、多少のオーバーヘッドが発生する。
パターン③ 共通処理をサイドカーとしてデプロイする
今回の推しはこれ。
汎用的な処理を共通のライブラリとして配布することができ、かつ、単一障害点になることを防げるというもの。
サイドカーの場合、メインのコンテナとライフサイクルを共にするので、どちらかだけ死ぬみたいなケースは防げるし、仮にparseできないとなったときに、その影響度はマイクロサービス単位で閉じることができる。
また、pod内通信になるので、マイクロサービス間の通信よりもオーバーヘッドが少ない。
さらに、今回のリプレイスという文脈においては、マイクロサービスにしてしまうと、全部のリプレイスが終わるまでParse APIを残す必要があるが、sidecarにしておけば、レガシーCMSへのリクエストがなくなったマイクロサービスから順次、サイドカーを無くすという選択がとれるので、段階的な縮退ができる。
結論
今回は大人の事情がありパターン①を選択したが、いろんな観点からとりうる選択肢を比較してみるのが良さそう。
思考停止でマイクロサービスのではなく、サイドカーという選択肢も持っておくことで、サービス(ドメイン)まで大きくないけど、汎用的なものを共有してメンテナンスしていきたいというユースケースに応えられると思うので、積極的に活用していきたい。