この記事はMicroservices Advent Calendarの1日目です。
Microservicesとの関わり
最近Qiita:Zineでも取り上げられましたが2017年春から社内でMicroservicesについてパイロットプロジェクトを立ち上げて検証をしていました。実サービスへの適用はまだありません。
技術異質性とは
マイクロサービスアーキテクチャは独立性の高い(疎結合な)複数のサービスを組み合わせるアーキテクチャなので、サービスごとに異なる技術スタックを採用することができるというメリットのことです。
各サービスは完全に別のWEBアプリケーションとして作成されるので、アプリケーションフレームワークはもちろんのこと利用言語もバラバラで構成できます。
やってみた
条件
- BFFあり
- サービスは3つ
- BFFと3つのサービスに主担当はそれぞれ1人ずつ
- コードレビューはクロスで実施
- 利用言語
- BFF: JavaScript
- サービスA: Go
- サービスB: Ruby
- サービスC: Haskel
検証の一環だったので言語からあえてバラバラにしていました。
どうだったか
正直しんどい。
特にコードレビューで経験の浅い言語を読むことになる状況だったので、コードレビューがあまり意味をなしていなかった。
ただし当然ながらシステム全体としては不整合なく動作する状態にはなった。これが実現できる事自体がモノリシックな構成に対して大きなメリットではあると感じた。
考えてみる
技術異質性を実現するためにはいくつか条件があると感じた。
1. サービスごとにチームがあること
一番わかりやすかったのはコードレビューの難易度だった。別のサービス担当(=別の技術スタック利用者)がレビューを担当するのは現実的ではないと感じた。レビュアーは同じ言語、同じフレームワーク(、できれば同じコードスタイル)を利用している人が担当すべきだと感じた。
ただこれについては検証プロジェクトゆえに担当者が1人ずつだったというのもあるので、実際の開発では自然と解決される気もする。でもサービス掛け持ちでの開発の話もよく聞くからやっぱりしんどいかも。
2. 不必要に異なる技術スタックにしない
あくまで「異なる技術スタックを利用できる」のであって、「積極的に異なる技術スタックにすべき」ではないと感じた。特に記述的な要求がない場合には各サービスでの技術スタックを共通化(せめて数パターンのどれかに)しておくに越したことはない。
特定のサービスに対して技術的な要求がある場合に異なる技術スタックを選択可能である、と考えたほうが良さそうだった。例えばノンブロッキングな非同期処理をしたいからNode.jsやKotlinを選択するといった場合や、高度な検索処理を行いたいからElasticsearchを中心に据えたシステムにするといった場合が該当すると思う。
そういった要求がない通常パターンのサービスについてはシステム内で共通スタックを定義しておいたほうが開発効率は担保できるはず。
3. 通信プロトコルもできる限り揃える
今回意図的にGo言語で作成したサービスはgRPC、それ以外はRESTで通信する仕組みを試してみましたが、BFFからの呼び出しがしんどかったです。gRPCの扱いに慣れていなかったのもあるかもしれませんが、このあたりも必要に迫られなければ揃えておいた方がよいと感じました。あとやっぱりRESTの方がテストツールなどのエコシステムが手軽に使えるものとして充実しているというのは強いです。
今回は試していませんがGraphQLなども混ざってくると更に大変になるのかなと思います。呼び先によって呼び方を変えないといけないのは(主に)BFF実装時の負担が増えます。
このあたりはPub/Subを使ったイベント駆動アーキテクチャにすることで吸収できそうな気もしますが、今回の検証では対象に含めていないので今後試してみたいと思っています。
まとめ
マイクロサービスアーキテクチャでは異なる技術スタックは混在できるが、特別な理由がない限りは技術スタックを揃えておいて、必要に迫られたときに選択肢を狭めないための特性だと認識しておくくらいが良さそう。
遅刻での投稿となってしまいましたが以上です。
次は12/6に投稿される @takegamm さんです。