2011年7月9日土曜日

g3 (クラウド温泉@小樽)

8月27日(土)/28日(日)に開催されるクラウド温泉@小樽に向けて、現時点でのg3/g4/SimpleModelerの技術について整理しておこうと思います。

Scala DSLベースのモデルコンパイラSimpleModelerでは、当初Glassfish(Java EE)、Spring、Google App Engineといったクラウドプラットフォームあるいはその上で利用するフレームワークのAPI上に直接プログラムを生成することを目指していました。

実際に、Google App Engineでのプログラム生成を実装したところ、生成するプログラム側で相当な作り込みが必要となり、ある意味フレームワークそのものを生成するような形になってしまうことが分かりました。結局、共通部品として必要なものは、自動生成ではなくフレームワークとして独立して提供するのが筋ということですね。

クラウドアプリケーション向けのフレームワークとしては、既存のフレームワークを流用するのが有力な選択肢です。Java EEやSpringといったエンタープライズ向けのWebフレームワーク、あるいはMule ESBやCamelといったESBについても比較検討したのですが、ボクが必要としている機能とはまだま距離があるということで、新規に開発することにしました。

こうして開発したのがg3フレームワークです。


目標

g3を一言で表現すると『Scala DSLベースREST指向粗粒度非同期コンポーネントフレームワーク』です。


  • フレームワークのアプリケーションインタフェースにはScala DSLを用いる。
  • 粗粒度のコンポーネントを非同期で連携してアプリケーションを構築する。
  • コンポーネント間の連携にはRESTを用いる。
開発時に念頭においていたのはEIP(Enterprise Integration Patterns)です。EIPによって非同期コンポーネントをAtomPubのフィードメッセージで連携するアーキテクチャがクラウドアプリケーションの一つの形ではないかというのが基本アイデアになっています。

プログラミングモデルとDSL

クラウドアプリケーションのアプリケーションアーキテクチャとしてどのようなものが適切かというのはまだまだ未知の領域ですが、ボクが仮説として考えているのが並行動作する粗粒度コンポーネントをメッセージングで接続する、コンポーネントベースのアーキテクチャです。 粗粒度コンポーネント間の連携プロトコルとしてRESTセマンティクスを用いることで、プログラミングモデル上、インターネット空間とシームレスに接続することができます。

Scala DSL

このアーキテクチャを取るときの論点の一つが、コンポーネントの組立てをいかに簡単に記述するのかという点です。このようなコンポーネントの組立てにXMLを用いるのが従来の手法ですが、以下の問題があります。まず、XMLによる定義は記述が煩雑になってしまうこと。また、プログラミング言語とのシームレスな連携ができないので、プログラミング言語とXMLの二本立ての管理になってしまうという問題もあります。関連して、定義ファイルにプログラミング的な技法、たとえばマクロを導入して定義の共通部をまとめることにできるようにする、いったことを実現することも困難です。 この問題を解決するために採用したのが、Scalaをホスト言語にしたDSLです。専用言語であるDSLを用いることで、メッセージングによるコンポーネントの連携を簡潔に記述することができます。 また、Scalaを通してScalaだけでなくJavaやその他JavaVM上で動作するプログラミング言語で記述されたプログラムと連携することができます。

REST指向

REST指向は、Webプロトコルとのシームレスな連携、フレーム内リソース識別のURI化、コンポーネント連携に用いるメッセージをAtomフィードベースにしていることにより実現しています。

イベント駆動

クラウドアプリケーションは非同期に発生するイベントを受けて動作するイベント駆動で処理する構造がアプリケーションの基本アーキテクチャになるというのがボクの仮説の一つです。 比喩的には、割り込みハンドラーとシステムアクティビティでアプリケーションを構築する組込み機器のような構造をイメージしています。 イベント駆動はまだ実現できていませんが、その前提となるメッセージの到着を起点に処理を駆動するメカニズムは実現しています。エンティティとして永続管理するビジネスイベントと、揮発性のシステムイベントをどのように再構成して、フレームワークのアーキテクチャ上に位置付けていくのか考慮中です。

状態機械

イベントの発生を受けて、発生したイベントとリソースの状態の組に対して、適合するアクションを実行するというのが、オブジェクト指向の動的モデルの基本的な考えです。 イベント駆動型のアプリケーションでは、この状態機械による動的モデルの記述と実行が重要な意味を持ってくることになります。残念ながら現状のオブジェクト指向言語では、状態機械のサポートを行っていないのでプログラムで直接記述することができません。 このメカニズムをフレームワークで実現したいというのもg3の目的の一つです。 プログラミング言語でサポートされていない必須機能をフレームワークで実現するわけですが、Scala DSLによるアプリケーションインタフェースを用いるので、ある意味新しい専用言語を導入するのと同じインパクトがあります。 状態機械の記述方式と上流モデルとの連携方法について、前述のイベント駆動のメカニズム、記述方法と合わせて検討中です。

スケーラビリティ

クラウドアプリケーションでは、スケーラビリティも重要な要件です。すべてのアプリケーションがフルにスケーラビリティを追求する必要はありませんが、必要に応じてスケーラビリティを確保する手段をモデリング、アプリケーションアーキテクチャ、フレームワークといった様々な層の技術の中に事前に織り込んでおく必要があります。 g3はスケーラビリティ確保の手段として非同期メッセージング、KVSのサポートを行っています。 非同期メッセージングとして前述したようにREST指向のメッセージを粗粒度コンポーネント間でパイプライン的に流通させるモデルをとっています。現在はまだ実現できていませんが、CPS(Continuous Passing Style;継続渡しスタイル)的な処理の記述や、メッセージキューを媒介にした非同期処理などを取り込める構造になっています。 また、データストアのスケーラビリティについてはKVSを包含したデータアクセス基盤を用意しました。 KVSも、Redisのように本当のKey/Value対のデータストアもありますしGoogle App Engine DataStoreのようにISAM的なデータ構造を持っているものもあります。以上の点から、KVSといってもISAMデータ構造、要するに単純な表形式のデータ構造を扱うようにしています。 クラウドアプリケーションでは、一貫性重視の用途にはRDBMS、スケーラビリティ重視の用途にはKVSを使い分けることになります。その場合、RDBMSとKVS間でデータを持ちまわる処理も普通に行われるのでKVSとRDBMSに対する統一アクセス法が欲しくなります。 また、このアクセス法はREST指向アーキテクチャ上で使用することになるので、RESTとのシームレースに連携できることが必要です。 g3では上記の要件を満たす統一アクセス法をサポートしました。REST指向アーキテクチャに沿って普通に処理を記述するだけで、特に意識することなくKVSを使用することができます。(もちろん、KVSをスケールさせるためにはキーの選定など特別な考慮が必要になりますが、疎通レベルでは簡単に使えるというのも重要です。) なお、SQLを直接使用したアクセスも可能ですし、Javaを直接使ってJDBCを使用することもできるので、必要に応じて使い分けすることもできます。

各種機能

実用上有用な機能として以下の機能を実装しました。
  • Web Socket
  • Ext-JS対応
  • 各種クラウドサービス用ドライバ(Twitter, Google Calendar, Dropbox, Evernote)
こういった、各種Web技術、クラウドサービスの取り込みは、必要に応じて順次行っていく予定です。

スコープ外の機能

g3の提供する機能という切り口とは別に、g3がスコープ外としている機能、後回しにしている機能が分かれば、g3の目的・意図が明確になると思います。 以下の機能はフレームワークの直接のスコープ外としています。
  • Web MVCフレームワーク
  • テンプレートエンジン
Web MVCフレームワークやテンプレートエンジンは、まだまだ改良すべき点はあるでしょうが、基本的には枯れた技術であり、再発明する必要性が薄いことが一つ。それより重要なのが、HTML5/CSS3によるAjaxやiOS/Androidといったスマートデバイスの興隆によって、技術の重要性が低くなりそうということです。 レガシー技術はそのまま再利用することとして、イベント駆動や非同期コンポーネントフレームワークといった既存の技術ではカバーしていない技術の実現を中心に開発を進めています。 通常のWebアプリケーションを開発する場合にg3を用いる場合には、既存のWebフレームワークと併用することになります。

次の段階で取り組むもの

以下の機能は、次の段階で取り組む予定にしています。
  • DI(Dependency Injection)
  • OSGi
  • JMX
  • Android
  • TDD/BDD
実用化フェーズでは必要なのは分かっているものの、基本機能が定まっていない段階で取り組むのは時期尚早ということで、将来の拡張を意識しつつも当面の開発項目からは落としています。

0 件のコメント:

コメントを投稿