yu-tarrrrの日記

完全に個人の趣味でその時々書きたいことを書く

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へのリクエストがなくなったマイクロサービスから順次、サイドカーを無くすという選択がとれるので、段階的な縮退ができる。

結論

今回は大人の事情がありパターン①を選択したが、いろんな観点からとりうる選択肢を比較してみるのが良さそう。

思考停止でマイクロサービスのではなく、サイドカーという選択肢も持っておくことで、サービス(ドメイン)まで大きくないけど、汎用的なものを共有してメンテナンスしていきたいというユースケースに応えられると思うので、積極的に活用していきたい。