マイクロサービスのデザインに関して個人的にはこう思う

2015年8月7日 | By TatsuakiSakai | Filed in: Micosoft Azure.

前回のポストでご紹介した通り、マイクロサービスの発想は全く新しいものではなく、ソフトウェアを部品化して組み合わせ部品を再利用するというアプローチはもはやソフトウェア業界の常套手段といっても過言ではありません。

つまり、これまでのアプローチとマイクロサービスには大きな違いはなく、単に実現手段が異なるだけです。

では、どのような方針でマイクロサービスを設計すべきでしょうか?

まず、大原則として、「マイクロサービスは独立した単機能である」ということを掲げておきます。

つまり前回ご紹介した通り、様々な依存関係を含む複合型のサービスはマイクロサービスとは言えない訳です。

ではどのように考えたらよいか、以下の例を基に考えてみましょう。

今あなたが旅行に行こうと思い立ったとしましょう。

国内、海外と様々な行き先がありますが、「○○に行こうか」と、場所が決まったとしましょう。

この際、あなたはどちらの行動を取りますか?おそらく、以下の2パターンに分類できるかと思います。

第1のパターンは、旅行代理店に出向きパッケージツアーのパンフレットを入手したり、雑誌やネットなどでパッケージツアーの情報を探したりするケースです。

おそらく旅慣れていない方はこちらのパターンが多いかと思います。

なぜなら、この場合は航空券(または列車などの交通機関)やホテル(旅館)、アトラクションなどの詳細はパッケージツアーの企画者にお任せできるからです。

第2のパターンは自身で交通機関やホテルの空き状況を検索し、自身で現地の観光情報を探すパターンです。

頻繁に訪れる場所への旅行や旅慣れた人の場合はこちらのパターンかもしれません。

一口で「旅行を計画する」といっても、このようにアプローチが異なります。

しかし、両者の行動には違いがあるものの、実は共通する部分があります。

一見、全く異なるように見えますが、両者には「外部のサービスを利用する」という共通点があるのです。

パッケージツアーのパンフレットも、航空便のスケジュール照会も、誰かの提供するサービスであるのは異論ありませんよね?

単に入手できる情報の粒度が異なるだけの違いです。

前者は日程からフライト、宿、現地の交通、市内観光まですべて揃った形で情報が得られます。

後者は、それぞれの結果が出てきて、これらの結果を基に自身で旅程を組みわせます。

ここでピンときませんか?そう、後者の解決方法はまさにマイクロサービスの組合せによる問題解決に類似しています。

しかし、パッケージツアーも「完全にお任せ」型のサービスとも限らず、航空会社、ホテル、滞在日数、オプショナルツアーなど選択肢が多くあり、これらの選択で成立していることに気付くと思います。

たとえば、特定の航空会社が良いとか、ホテルのグレードは4つ星以上に限るとか・・・。

言ってみれば、一見一枚岩に見えるパッケージツアーも、複数のマイクロサービスの組合せで成り立っていると考えることができます。

単純なパッケージツアーの構成は「航空便検索&予約」、「宿泊先検索&予約」、「オプショナルツアー検索&予約」のマイクロサービスから構成されます。

仮に、複数の都市に滞在するような場合でも、これらのサービスを滞在都市分だけ繰り返し利用するだけで旅行プランは概ね作成できます。

そして、これに「レストラン検索&予約」などのサービスも加われば、旅程の計画と予約は完璧でしょう。

また、こうした一枚岩のサービスを分割したものを、マイクロサービスとして切り出しWeb APIを公開していたとしたら、外部のサイトやサービスから利用可能になります。

この様に、特定のビジネスシナリオをベースにしたアプローチで、マイクロサービス化していくことができます。

これも、1つのアプローチとしてされて有効でしょう。また、こうしたサービスは多くの場合外部サービスにより再利用されることを想定しています。

もう1つのアプローチとして、技術的側面から複数のマイクロサービスに分割するアプローチも存在するでしょう。

これは、再利用性よりも単独のアプリケーションのスケーラビリティやセキュリティの最適化を優先するアプローチとなります。

先の旅行予約の例を挙げれば、航空便の検索と予約では負荷の集中するタイミングやトラフィックが異なります。

フライトスケジュール検索は平均的にトラフィックが発生し、旅行シーズンに検索が集中するかもしれません。

予約は検索ほどの負荷増大は無いかもしれませんが、予約開始日や割引運賃適用期限前に集中することが予想されます。

検索、予約のそれぞれを最適化するのであれば、これらのサービスを分離した方が望ましいでしょう。

たとえば、「検索」では乗継を含めたフライトスケジュールの検索機能を提供するサービスとして提供し、「予約」は各便の空席照会と予約機能を提供するサービスとして提供します。

この様に、フライトの手配は「検索」と「予約」の2種類のマイクロサービスから構成されるようにしておけば、それぞれを独立して配置・実行することが可能です。

また、予約に関しては決済を伴いますので、セキュアなサービスとして分離することも求められるでしょう。

ここで注目してほしいことは、技術的側面からサービスの粒度が決定される場合においても、必ずビジネスシナリオを実現する1ステップ単位でマイクロサービスが分割さていることです。

どうしてもアプリケーションを分割するとなると、「UI」、「ビジネスロジック」、「データコンポーネント」といったn層型アプリケーション的な分割を考えてしまいがちですが、マイクロサービスはこうしたアプローチとは視点が異なります。

そもそも、マイクロサービスはバックエンド処理を提供することを想定しているかも知れませんが、この場合でも分割単位は「ビジネスロジック&データコンポーネント」ではなく「ビジネスシナリオ&ビジネスシナリオのステップ」となります。

あくまで個人的な意見ですが、マイクロサービスの粒度を決定する際、以下のようなチェックポイントで検討すると良いと考えます。

 

・インタフェースを介してサービスの提供機能を独立させることが可能であるか?

・1セットの機能(CRUD操作等)に集約されているか?

・呼出しの頻度が多すぎることなく、サービス間の関係が疎結合になっているか?

・サービスのライフサイクルは独自に決定可能か?

 

また、サービス間はWeb API (HTTPS)やメッセージ・キュー(AMQP)等のインタフェースを用い、コントラクト(受け渡されるデータ形式)はJSONやCSVなど、比較的軽量なテキストで受け渡されることが望ましいでしょう。

また、参考になるアプローチとしてドメイン駆動アプローチがあります。

Microsoft のドキュメントではPatterns & practicesの各種ガイダンスが参考になると思います。

最後に、「悪戯に細かなサービスを量産しない」ことが、マイクロサービス活用の成功への近道だと考えます。


Comments are closed here.