2021年3月31日水曜日

SimpleModeling/Component

SimpleModelingでは、コンポーネントをソフトウェア開発を行う上での中軸となるモデル要素と捉えています。今回はコンポーネントのメタモデルを検討します。

コンポーネントはオブジェクトやサービス、システムと同様にメタモデル上は分類子(classifier)を親としており分類子の構造を引き継いでいます。コンポーネントのメタモデルの検討を行うのはコンポーネントのメタモデルを軸に、上方向ではサービスやシステム、下方向ではオブジェクトのメタモデルを考える上でのベースラインにする狙いもあります。

Componentの構造

SimpleModelingではComponentの構造を以下の図に示すメタモデルをベースにメタモデルの検討を行っています。

以下でそれぞれのモデル要素についてみていきます。

API

本案では以下の3つのAPIを定義しました。

  • Service API
  • Management API
  • Resource API

APIではOperation群を定義します。

Operationの実装はプログラム言語のメソッドが基本で、必要に応じてRESTを含むRPCとして実装します。

Service API

コンポーネント利用者向けのAPIです。

Webなどフロントエンド・アプリケーションやその延長線上にある他コンポーネントからの利用を想定しています。

Management API

コンポーネントの提供する機能やコンポーネントが管理するデータの運用管理をするためのAPIです。

管理コンソールやその延長線上にある他コンポーネントからの利用を想定しています。

Resource API

リソース操作用のAPIです。

リソース操作用のAPIは個々のOperationの責務は前述のService API、Management APIに分類されるため分類上の重複がありますが、モデルからの自動生成の対象なので図では独立した形で記述しています。

SPI

SPI(Service Provider Interface)はComponentに対してサービスを影響するコンポーネントやオブジェクトを接続するためのインタフェースです。

たとえば、ECシステムで外部の決済サービスを利用する場合、決済サービスを呼び出しすためのドライバを作成しSPIを通じてコンポーネントと接続します。

SPIを経由して接続する外付けのプログラムでComponentの機能を拡張していくことができます。このため、SPIはComponentの拡張点(Extension Point)ということができます。

Bus

クラウド・アプリケーションを開発する上で重要な構成要素がBusです。クラウド・アプリケーションはクラウド内で発生する各種イベントに即応するためイベント駆動型の振舞いが極めて重要です。単純にAPIが提供するOperationを呼び出すだけの処理ではまかないきれなくなっているわけです。

このクラウドワイドなイベント駆動処理の基盤となるのがBusです。

SimpleModelingではBusを第一級の構成要素としてメタモデル上での扱いを明確にし、SimpleModelerやKaleidoxといったツールでもBusの使用を前提とした機能セットを提供する予定です。

Busには以下の示す特性があります。

  • イベント駆動
  • 透過性
  • 疎結合
  • 非同期
  • スケーラビリティ
  • 可用性(availablity)

これらの特性はクラウド・アプリケーションを構築する上で重要な役割を担います。

Busも用途に応じていくつかの種類が考えられます。図では以下のBusを示しています。

  • Service Bus
  • Inter-Component Bus
  • Async Bus
  • Sync Bus

それぞれ見ていきましょう。

Service Bus

ネットワークワイドでコンポーネント間の同報通知を行うバスです。

Apache KafkaやAWS SNS、AWS Kinesis、AWS EventBridgeといったサービスの利用を想定しています。

基本のBusとなります。Service Busを使うことでComponent内のObject間通信もインターネットワイドなサービス間の通信も透過的に行うことができるので、理想的にはService Busのみを使用するのが望ましいといえます。

ただ、現実のアプリケーションではさまざまなニーズが存在するので、それらのニーズをすくい取るためにメタモデルでは用途に応じたBusを定義しています。

Inter-Component Bus

同一プロセス内でComponentを接続するバスです。

通常のOperationに対してBusを使う上での問題点として以下のものがあります。

  • 非同期になってしまう。
  • データベース・トランザクションの制御から外れてしまう。

非同期の問題点はエラー情報をその場ではクライアントに伝えることができなくなることです。このため大掛かりなエラー処理の仕掛けを作る必要が出てくるのでアプリケーション開発の複雑度が一気に増加します。

いうまでもなくデータベース・トランザクションから外れてしまう問題もエラー処理の複雑度が大きく増加します。

もちろんBusの提供するイベント駆動、透過性、疎結合の特性は魅力的です。

そこで同一プロセス内で動くComponentやObject間の協業では、本来同期型&トランザクションは可能なはずなので、イベント駆動、透過性、疎結合の特性を持ちつつ、同期型&トランザクションのサポートを行うBusとしてInter-Component Busを用意しました。

Async Bus と Sync Bus

Component内部で使用するBusです。このメタモデルでは以下の2つに分けています。

  • Async Bus
  • Sync Bus

いずれもComponent内に閉じていることにより効率的な実行を想定しています。

Async Busはシグナルの同報処理を非同期で行うバスです。Service Busと同じ特性を持ちます。

Sync Busははシグナルの同報処理を同期で行うバスです。Inter-Component Busと同じ特性を持ちます。

Async BusとSync Busは、プラットフォームによってはそれぞれService Bus、Inter-Component Busを直接使用する方式でよいかもしれません。

Object

Component内には用途ごとに各種オブジェクトが存在することになります。

図では以下のObjectを図示しています。

  • Service API, Management API, Resource APIを司るObject
  • SPIを司るObject
  • Bus(Async Bus, Sync Bus)に接続したObject
  • Entity
  • 図の中央にあり各Objectを中継しているObject

StateMachine

Objectのメタモデルを定義する上で重要と考えているのがState Machineです。本来オブジェクト指向の動的モデルはState Machineを使ってモデル化するのが筋ですが、既存のプログラミング言語に該当する機能がないこともあり、一般のエンタープライズやWebアプリケーションでは現状はほとんど利用されることがないと思います。

しかし、イベント駆動が重要な位置を占めるクラウド・アプリケーションではStateMachineが動的モデルの要のモデルです。このためSimpleModeingではStateMachineをメタモデルで定義し、SimpleModelerやKaleidoxといったツールで直接使用できるようにする予定です。

Entity

データベースに格納して管理するPersistent ObjectをSimpleModelingではEntityと呼びます。

SimpleModelingではEntityはデータベース内にあるため直接操作はせず、一旦メモリ内のObjectに転記し、転記したObjectで状態を更新した上ででデータベース上のEntityに書き戻すと、という操作モデルを取ります。

メモリ内のObjectに転記する場合に、必ずしもデータベース上のEntityのクローンである必要はなく、アプリケーションのモデルに応じたメモリ内のObjectに必要な情報を転記することになります。

EntityはStateMachineを持つことができます。実装的には、Entityをメモリ上に展開したObjectにStateMachineを定義し、そのStateMachineが動作するという形になります。

設定

Componentの振舞いをComponentの想定した範囲で変えるための変化点(Variation Point)のメカニズムとして以下の2つを用意しました。

  • Configuration
  • Rule

Configuration

ロケールやタイムゾーンといったアプリケーションの国際化情報やタイムアウト時間など、Componentの基本的な振舞いに対するパラメタ設定を行います。。

格納場所は配備時にファイルを添付したり、外部のリポジトリに格納といった手段が考えられます。

Rule

アプリケーションがモデル化したRuleを、アプリケーションのユースケースに合わせて設定します。

消費税率といったパラメタ的なものから、エキスパート型AIの推論ルールのようなものまでを想定しています。

記録

運用上の様々な要件からコンポーネントの動作記録を取っておく必要があります。

  • Log
  • Metrics
  • Audit trail

Log

動作ログです。

アプリケーションの各種メトリックスの計算、デバッグ情報、性能改善の基礎データ、課金情報として用いることを想定しています。

上記の用途に必要な情報を採取できるよう、ログとして採取する情報についても分析・設計が必要です。

Audit trail

セキュリティの監査記録です。セキュリティ監査のための基本情報としてユーザーがComponentをどのように使ったか、どのリソースを参照・更新したかの記録を取ります。

Logよりも厳密な情報を採取する必要があるので、モデルを分けています。

Metrics

コンポーネントの振る舞いをデータ化したメトリックス情報です。オペレーションの呼び出し回数やキャッシュのヒット率といった情報を記述します。

性能改善の基礎データや課金情報として用いることを想定しています。

まとめ

今回はSimpleModelingで重要視しているモデル要素であるComponentについてメタモデルを検討しました。

次回はこのメタモデルをベースに、ComponentをKaleidoxで扱う方法について考えてみます。