アプリケーション構成
作成したアプリケーションの構成、動作イメージとしては、下図のようになります。
アプリケーションへの外部インターフェースとしてはRESTだけではなく、MQ経由でのメッセージも受け取れるようにしています。REST経由もMQ経由も内部で同様のJSON形式に変換され、パラメータのバリデーションが行われます。バリデーション後、ワーカースレッド上で各業務処理を行うためのトランザクションモジュールが処理を行います。この業務処理部分では、場合によって外部のAPIを呼び出すためのHttpClientモジュールを非同期で呼び出しますが、DBとのトランザクション部分は同期型で通常のJDBCを使って処理を行っています。
サンプルで使用したmod-jdbc-persisterなどを使わなかった理由としては、前回のサンプルソールを見ていただければ分かると思いますが、そんなに複雑でもないUpdateのトランザクションがネストだらけの見づらいソースになっています。RxJavaなどを利用すればもう少し見やすくできるとはいえ、決してメンテナンス性の高いソースではありません。
非同期な形で処理を記述した場合も、結局はWorkerスレッドで処理が行われているに過ぎず、トータルのパフォーマンスが改善されることも考えられません。それであるならば、Javaの経験者であれば誰でも書きなれたトランザクション処理の記述方法ができるようにこの構成を選択しました。
Rest Module
その名のとおりRESTインターフェースのためのモジュールになります。基本的にはVert.xのHttpServerの機能を利用した単純なHTTPの送受信を行うモジュールですが、HttpパラメーターのJsonObject変換など、内部仕様に依存した後続の各モジュールのための初期処理も行っています。また、HTTPのコネクションタイムアウトの機能がなかったため、一部修正をいれています。
MQ Module
リクエストの多くなる処理用のインターフェースとしてMQにも対応しています。REST時と同様のメッセージに形式を変換する機能とRPCに対応した仕組みを持っています。
Validation Module
メッセージがJSON形式になっているため、JsonSchemaを利用してバリデーション項目を定義することで簡単に条件変更可能な仕組みを作成しました。
Transaction Module
ワーカースレッドで各ビジネスロジックを実行するモジュールになっています。基本的にスレッドや別モジュールを意識せずにシンプルなトランザクション制御を実装するようにしています。
HttpClient Module
Vert.xのHttpClientを利用し、アクセス先ごとに細かい設定やコネクションプールを使用できるように作成しました。
crashub/mod-shell
図にはありませんがsshやtelnetでCUIによるコマンド制御を可能にするために、Crashubを利用できるmod-shellも使用しています。これによってシェルスクリプトなどからプロセス制御を行っています。
Vert.x2.1系の所感
実際にVert.xを使ってみると実運用には機能が足りないため、他にも起動順序制御のためのライブラリや、いわゆるGracefulな停止を実現させるための仕組みなど、かなり作りこみを行っています。本格的に実業務で使いこなすためには、それまでのServletなどの知識が使えず、情報量も少ない中で調べること、作るものも多いために少々ハードな作業が必要でした。
正直なところ、v2.1の段階では万人にお勧めできるフレームワークというには難しいですが、最近のマイクロサービス化という流れの中では、こういった重いアプリケーションサーバーを使用することのない軽量なフレームワークの仕組みを理解することは非常に有益なことだと考えています。
ここまではVert.x v2.1.5でのアプリケーションでしたが、ここからはつい先日リリースされ、大幅に進化した最新のv3.0についてご紹介したいと思います。