マイクロサービスつらいorz
過去のマイクロに振り切ろうとした(そして諦めた)経験を踏まえ、自分の考えるマイクロサービスのいいところとわるいところをまとめる。 多分、オライリーの本とかに同じようなことが書いてある気がする。
分ける対象
分ける対象は以下
以下それぞれ分けたときのメリット、デメリットをまとめる。
プロセスを分ける
Tomcatに複数サービスを相乗りさせているのを別々のサーブレットコンテナに、一つのバッチジョブで複数ステップ処理しているのを複数のジョブに分けるとか
メリット
- リリースしやすくなる
- 処理によってリソースを最適化できる
- スケーラビリティを確保できる(APIであればロードバランシング、ジョブであれば処理対象を分けて並列処理など)
- 部分的に再実行しやすい(ジョブを分けたパターン。フレームワークによっては失敗したステップから再実行できるものもある(例:SpringBatch))
デメリット
- 複数のサービスを同時にリリースしたい時にリリースのタイミングを合わせないといけない場合の手間
- 通信エラーのハンドリングのための作り込みが必要(データストア、HTTP通信など)
- プロセス間のデータのやりとりのための作り込みが必要(処理結果をJsonにシリアライズしてファイルに保存するなど。オブジェクト指向のプログラミングをしている場合は、型をシリアライズした先でどう表現すればいいか悩まされる)
- 前提となる処理のエラーや処理が遅延するケースの制御の作り込みが必要(前の処理が終わっていないのに後続が走り出すとマジでジーザスなことが多い)
- ACIDの実現のために作り込みが必要(RDBのトランザクション管理機能で実現してきたようなこと。一貫性についてはactivatorパターン - doilux’s tech blogというのを考えたこともある)
作り込みという文字を強調したのは、自分は作り込むことが死ぬほど嫌いだからです。作り込みが多ければ多いほど、バグが混入するリスクも多いし、運用保守の手間がかかるので。
ソースコードを分ける
一個のgitのレポジトリを、サービス毎に複数のレポジトリにわけるとか
メリット
デメリット
- ソースコードを追う時にあっちこっち参照しなきゃいけなくてめんどくさい
- ライブラリの管理が大変(脆弱性が見つかってバージョン上げる時とか)
- うまく共通部分を分離しないとコードが重複する
- 言語やフレームワークを変えられるがスキル(人間)がついていけないことが多い(教育コストがかかる。しかも開発人員だけではなく、運用保守人員にも)
- テストコードだけで完結しないテストが多くなる
データストアを分ける
DBMSをわけるとか
メリット
- 処理や管理するデータに応じてデータストアを選択できる(RDB、列指向DB、KVS...etc)
- 処理や管理するデータに応じて運用をカスタマイズできる(バックアップのポリシーなど)
- データへのアクセス権限を管理しやすい
デメリット
チームを分ける
システムの開発・運用保守するチームをサブモジュールごとにわける
メリット
- サービスに応じた開発プロセスを採用しやすい
- サービスに合わせた人材の採用・育成
- 共有コストが下がる(異なるチームは細部をしらなくていい)
デメリット
- コミュニケーションコストが上がる?下がる?(プロパー、委託社員の比率や会社の文化による)
結局どうなん
基本的には、分けると開発のしやすさと引き換えに運用コストや教育コストがかかると思っているので、コストに見合った価値を期待しているなら分けたほうがいいと思います。あと、最初から分けないほうがいいかと。後から分けるの大変じゃね?って意見もあると思うけど、運用コストが増えたわりに事業がスケールしないってこともあるので。