🍙

マイクロサービスアーキテクチャー化に関する考察

2022/05/24に公開

はじめに

  • 各種の巨大なレガシーシステムを現行のトレンドであるサーバレス、マイクロサービス化へ刷新するにあたり、どのような進め方が良いか、情報を収集して検討した。
  • 大規模なシステムのマイクロサービス化の成功事例はあまり情報が無いので、どのようにプロジェクトを進めてマイクロサービス化できたのか知りたい。

フロントエンド

  • 開発言語はTypeScript + REACT + (Next.JS) が主流。
  • フロントエンドは、関数コンポーネントで動的なデータを関数経由で状態管理して画面表示する。バックエンドへはREST APIなど単純な処理でデータを連携させる。
  • UIは時代に合わせて変遷できるようにする。(一番ハードル低くDX化できる) なのでなるべく複雑なビジネスロジックは持たせないようにする。
REACT
  • REACTは、静的なHTMLや、動的なJavaScript部分含めてすべてクライアントサイドにてレンダリングを実施する。(プリレンダリング機能が具備されていない。)
  • REACT HOOKSにて状態(State)管理を行う。
  • Stateが変更されると各コンポーネント単位で、再レンダリングされる。コンポーネントは画面要素の単位。粒度は様々であるが、再レンダリングの範囲を制限するための設計が必要になる。
NEXT.JS
  • NEXT.JSは、SSG(Static Site Generator)と呼ばれる事前にビルドして静的なHTMLを作成できるプリレンダリング機能が具備されている。規模の大きなサイトを運用している場合は、読み込みに時間がかかる可能性があるので、NEXT.JSが採用されるシーンが多くなってきている。
TypeScript
  • JavaScriptを避けて、型安全な開発言語を採用する。
  • TypeScriptでルール化された環境下でコーディングを行い、JavaScriptに変換してデプロイする。

バックエンド

  • 前段のフロントエンドはAPIを叩く等、ライトウェイトな処理であるが、バックエンドは重い業務処理を行っている。
  • ドメイン層が最上位のドメインパターン3層構造でDTO経由でデータを渡し、ドメインロジックを実装するといったオブジェクト指向言語の世界となっている。
  • 複雑な業務ロジックではあるが、依存関係逆転の原則に従った抽象レイヤであるインタフェースが具備されている可能性が高い。
  • エンドユーザに公開されているインタフェースが存在するとした場合、それを活用することを検討したいが、具体的にインタフェースを利用する方法が不明。提供アプリケーションをライブラリ的にプログラムに読み込む処理が必要になるか。

サービス構成

  • フロントエンドとバックエンドで分離した場合、その間の接続について検討する必要がある。
  • フロントエンドからバックエンドへの呼び出しは簡易なAPI経由が良い。バックエンドがAPIを持たない場合や、各種システムのAPIを複数呼び出す場合、WrapするAPI層を中間にもうけて、ここでビジネスロジックを持たせるのも良いかもしれない。
  • そのように考えていると、BFF(Backend For Frontend)アーキテクチャの考えが近いとわかった。
    • BFF(Backend For Frontend): フロントエンドとバックエンドの中間に配置され双方の複雑な処理を緩和させる責務を持つアーキテクチャ設計パターン。
    • バックエンドシステムの中間APIとして機能する。フロントエンドには、分かり易いAPIを提供するが、ここの実装にビジネスロジックを加える、実装が複雑になる可能性がある。
    • BFF 〜 バックエンドはAPIが望ましいが、バックエンドはレガシーなので、ODBCとかでもWrapしてAPIとして提供するのもあり。
    • BFF配下の各種システムはマイクロサービスに分離されたアークテクチャが望ましいが、そもそもレガジーなモノリスシステムを分離することはかなり困難。
    • 分離したシステム間でもシステム連携があり、複数システムをまたがった場合、分散トレーシングによりサービスが呼ばれた順序や状態を可視化できるが、そもそも前提として、各システム間の接続方式や接続仕様が定義されていなければならない。
    • つまり、モノリシックなシステムAがあり、それをマイクロサービスに分割し、サービス領域別に再配置することとした場合、分割する粒度(システムA-1, A-2....)を決める、かつ、それぞれのシステム連携IFを定義しておく必要がある。その結果、システムA-1を切りだし、クラウド化となった場合、切り出した後のシステム連携IFがどうなるか確認・検証するプロセスが必要となる。既存システムとの連携IFやそもそもシステムA-1が具備する外部IF等。
    • 上記の難易度・連携IFの数でマイクロサービス化すべきか否か、粒度をどうするか検討できる。マイクロサービスにおいて、どういう単位で分割すべきかは、明確な答えはない。

留意事項メモ

  • オンプレからクラウド移行する場合、どの粒度でどの部分から実施するか。
    • 既存のオンプレシステムとのシステム連携をすべて洗い出す必要が出てくる。システム連携IFだけでも、膨大な数になる。
  • ここまではあくまでシステムの観点、クラウド移行でオペレータの業務フローに影響はないか等、業務の観点でも確認が必要となる。
    • AS-ISの業務フローからTO-BEの業務フローを作成すべきか、既存業務に影響を出さずに、既存フローを踏襲したフローを実施できるようにするか。
    • TO-BEの業務フロー検討は時間がかかるが、システム要件を洗い出すために実施すべき。オペレーターによる手作業も案外存在するかもしれない。

マイクロサービス化の進め方

  • フロントエンドのコンテンツはクラウド移行。AWS等を利用し、サーバレス構成とする。
    • フロントエンドの刷新化をDXの始めの一歩とする。
  • フロントエンドとバックエンドの中間に配置され双方の複雑な処理を緩和させる責務を持つアーキテクチャ設計パターンであるBFFを採用し、複雑なビジネスロジックを受けもつ。
  • バックエンドはマイクロサービス化を実施するか否か判断する。
    • マイクロサービスは「銀の弾丸」ではない、目的や目標の達成手段としてマイクロサービスが適切ではない場合もある。
    • システム連携IFが大量になる場合、モノリスのインタフェースを活用して、BFF側でビジネスロジックをまとめた構成のほうが移行難易度が低く実現可能性が高くなるかもしれない。
    • 逆に既存のリソースを最大限活かした移行方法も検討する価値がある。既存のオブジェクト指向言語をAWS Lambda化 する等してコードリファクタリングを最小限に抑える等。
その他
  • フロントエンドは若い世代の領域、REACTの更新頻度に追いつくのが精一杯。最近でもreact-router-domの最新v6 versionでは<Switch>タグが利用不可になっていたり、変化に対応するのに、おじさんはしんどいし、若い世代には勝てないなぁとも思う。
  • それに対して、バックエンドはオブジェクト指向の世界。昔ながらの開発手法で、年代の高いエンジニアが住居する。ここにフロントエンドの新たな手法がどのように取り入れられていくのか。オブジェクト指向は終わりに向かうのか、おじさんは楽しく見ているよ。
用語 詳細
モノリス モノリシック(一枚岩)。必要なコンポーネントがすべて1つのアプリケーションに含まれた構成。コーディングして、WAR,JAR等のアーティファクトに出力してデプロイする。
マイクロサービス アプリケーションの構成要素を独立したサービス群へ分割する。それらのサービス群を連携させることで1つのアプリケーションとして組みたてるアークテクチャ。
  • 新規構築であればマイクロサービス化がフィットする事例もあるが、巨大なモノリスのシステムをマイクロサービス化して、アジャイル開発で更改し、成功した事例があまり見当たらない。巨大なモノリスシステムを分割しても、アジャイル開発の粒度には至らないのではないか。マイクロサービス化する開発を行うより、既存システムのプラットフォーム移行(クラウド化・サーバレス化)と整理するほうが、良いのではないかなと思う。

Discussion