NServiceBus のバージョン 3.0 が先日リリースされた。InfoQ ではこの最新リリースに追加された新機能について,開発者である Udi Dahan 氏に話を聞いた。RavenDb との統合機能はそのひとつだ。RavenDb は Oren Eini (Ayende Rahien) 氏が開発した,.NET で記述された比較的新しいデータストア実装だ。InfoQ は氏から NServiceBus との統合について,さらには氏自身の Rhino Service Bus との関係についても聞くことができた。
InfoQ(Udi Dahan 氏に): NServiceBus とはどのようなものか,説明して頂けますか?
Udi: NServiceBus は .NET で分散システムを構築するための,最高の信頼性を備えたプラットフォームです。サーバクラッシュやデータベースのデッドロック,システムアップグレード時のデータ復帰エラーなどで,データを失う訳にはいきません – そのため NServiceBus は,WCF の標準をはるかに越えた機能と BizTalk 以上の性能を備えています。バージョン 3.0 ではオンプレミスに加えて,クラウド上でも動作可能になりました。
ActiveMQ や RabbitMQ,ZeroMQ などでメッセージング技術に精通した開発者にとっての NServiceBus は,マルチスレッディングやトランザクション管理,メッセージの定義,シリアライズとバージョニング,依存性注入,偽装(impersonation),暗号化といった,上位レベルで発生するやっかいな問題を解決してくれる存在です。これらすべてがビジネスプロセスエンジンに組み込み可能な – 開発者指向の軽量パッケージに含まれているのです。
InfoQ: NServiceBus 3.0 の機能の中で特に強調したいものを3つ選ぶとすれば,何を挙げますか? その理由は何でしょう?
Udi: バージョン3で気に入っている機能ということならば,遅延メッセージングでしょうね。未来の自分に宛ててメッセージを送るような機能で,実装はシンプルですが,効果は絶大です。長時間動作するプロセスにおいて,よりスケール性と継続性の高い状態管理を可能にします。例えば "買い手の後悔 (buyer’s remorse)" ,つまり注文キャンセルの大部分が購入後の短期間に発生する事実をモデリングしたビジネスプロセスを実装するとしましょう。SubmitOrder メッセージの処理では,一般的なロジックを実行してデータベースに状態を保存する代わりに,2時間後に自身が受信するようなメッセージを送り返すようにします。2時間というのは,その間に同じオーダ ID の CancelOrder メッセージを受信する可能性のある期間です。この時間内にキャンセルがあれば,データベース処理を1度も行わずに注文プロセスを終了することができるのです。一方でキャンセル通知が遅すぎた場合は,いくらかのキャンセル料が発生する,つまり全額の払い戻しはできないということをユーザに返答しなければなりません。このような状態遷移も,もっと長い遅延時間を伴ったメッセージを使えば管理可能です。完全に分散的かつスケーラブルなメッセージングトポロジ上で,このように複雑で絶えず変化するプロセスをモデリングできるということが,NServiceBus の強みなのです。
2番目に挙げたいのはモニタリングです。これに関して私たちは,非常にリーンなアプローチを選択してきました。多くのユーザがまったく意義を見いだせないままデータの洪水に溺れている様子を,これまでずっと見てきたからです。今回のバージョンでは,メッセージベースシステムにおいて最も重要な基準を,ひとつのカウンタに絞り込むことに成功しました。それが SLA 違反カウントダウンです。エンドポイントの SLA (Service Level Agreement) を (例えば 10秒に) 設定すると,NServiceBus がメッセージのキュー内での待機時間と処理時間を監視して, (現在と同じ負荷傾向が続くと仮定した場合に) エンドポイントで SLA 違反が発生するまでの時間を算出します。これによって管理者とビジネス関係者は,システムの各部分の状態を – CPU 利用率といった低いレベルの基準ではなく – SLA 違反というビジネス用語で確認することができるようになります。さらにこれを NServiceBus の持つロードバランス機能と併用すれば,結果としてシステムのどの部分にスケールアウトが必要か,それがどの程度の緊急性を持っているか,ということを管理者が確認できるようになります。ただしこのレベルの透過性を IT 組織のすべての人々が期待しているのかどうかは分かりません :-)
バージョン 3.0 で実施した拡張の中で,もうひとつ非常に重要なのが (あまり目立ちませんが) 拡張性に関する部分です。プラグイン可能なアーキテクチャは以前から採用していましたが,ここ数年 "パイプ内部で" 起きていることをもっと深くコントロールしたい,という要求がユーザから届いていました。技術面で先進的なユーザの多くはベータ版以前のバージョンから NServiceBus 3.0 を採用して,プロパティ単位あるいはメッセージ全体の暗号化や圧縮,オーバライド可能なルーティング,サードパーティ製の作業単位 (unit-of-work) とトランザクションの管理機能の統合などといった機能を実現しています。私たちのコミュニティが NServiceBus を signalR などのフレームワークに数行の (このような) コードで統合して,フルプッシュの (ここに示すような) オークションサイトなどを構築しているのを見るのは,とてもエキサイティングなことです。何しろ私たちの目標はずっとひとつ – 皆がクールなものを早く構築できるように何かできることをせよ,ということなのですから。
InfoQ: 導入作業の面で簡略化された部分,あるいは次期バージョンで簡略化される部分はありますか?
Udi: その方面では大きな改良が加えられています。堅牢なタイムアウト管理,マルチサイトかつクロスプロトコルな通信機能,クラスタ化されたメッセージ処理といった NServiceBus の先進的機能を活用する開発者のために「設定より規約 (convention-over-configuration)」モデルを導入して,これまでも少なかった設定項目を一桁近くにまで削減しました。
セキュリティ関連にも注目していて,管理者特権が必要になる場面を,ロックダウン中の本番環境以外ではインストール時のみに限定しています。これにはかなりのバランス感覚が必要でした。システム構築時の開発生産性を最大化するためには,必要ならばどのようなキューもその場で作成できなければならない一方で,本番環境はそれとはまったく正反対なのです。
さらにバージョン 3.0 では RavenDB (オープンソースの第2世代ドキュメントデータベース) を採用することで NServiceBus の動的ルーティングなどの稼働時視認性が大幅に向上し,管理者がデプロイ環境をより多く制御できるようになっています。
InfoQ: 今回のリリースに付属する RavenDB には追加のライセンス料が不要になっていますが,これはどのような契約方法によるものなのでしょう?
Udi: NServiceBus はどのエンドポイントがどこに接続しているかという情報や,長時間実行しているプロセスの状態を (電源断時などに) 保存するための永続化ストレージが必要です。これまでのバージョンでは,そのために開発者がデータベース接続を用意しなければなりませんでした。多くの組織では,これには DBA の承認が必要です (簡単であるとは限りません)。RavenDB の導入によって,開発者自身でソリューションを完成させることが可能になったのです。
RavenDB を選択した最大の理由は,分散トランザクションをサポートしているからです – これによって "最低1回" という条件のメッセージを処理するための重複排除ロジックを実装する必要がなくなり,NServiceBus で常に提供している完全な "1回のみ" モデルが手に入るのです。さらには RavenDB 開発チームのレスポンスのよさも大きな要因のひとつでした。
ライセンスに関して言えば,ユーザに複数ベンダとのライセンスという問題の解決を課したくはありませんでした。そのために私たち2組織の間で財務的な問題を解決して,ユーザには可能な限り簡単なものにしたのです。要するに NServiceBus の売上の一部が RavenDB に渡る仕組みなのです。すべての人々にメリットがある方法です。
InfoQ (Ayende Rahien 氏に): RavenDB を NserviceBus に統合した動機と,フリーライセンスモデルを採用した理由について教えてください。
Ayende: RavenDB の統合について, NServiceBus 側の観点から説明することはできませんが,私たちには大きな利点がいくつもあります。まず最初に,NServiceBus をリリースベースとすることによって,多数の企業へのエントリが得られることです。IT 組織や潜在的ユーザに対して,RavenDB が多くのユーザの本番環境で使用されていて,高負荷の厳しい環境下で苛酷なテストに耐えている,という安心感を与えられるのです。
さらに NServiceBus ユーザが RavenDB に接してくれることは,当然ながらこの主力製品のプロモートにもなります。
NServiceBus が内部的に RavenDB を使っていれば,そこからアプリケーションに RavenDB を導入するまでのステップはごく小さく,自然なものになります。RavenDB の提供する性能と機能,API がユーザに認められ,満足を得られることを私たちは確信しています。
リレーショナルデータベースでは非常に困難だったことが,そう,ごく自然に,簡単に実現できるのです。
InfoQ: ご自身でも以前 Rhino Service Bus という .NET 用サービスバスを開発されていますが,そのユーザは今回,NServiceBus への移行を検討するべきだと思われますか?
Ayende: Rhino Service Bus を開発したのは 2008 年頃のことです。以前に使った他のサービスバスに納得できなかったことが動機でした。私がサービスバスを開発した頃は,今とは関心や方向性が違っていましたが,それは4年も前の話です。その間に NServiceBus は大きく進歩して,とても使いやすい製品になりました。革新的な開発ストーリとして,非常によい形を取ってきたと思います。もしこれからサービスバスに取り組むとしても,自分自身で構築するという選択はまず考えられないでしょう。
InfoQ (Udi Dahan 氏に): NServiceBus の旧バージョン (最近のもの) から 3.0 への移行ストーリはどのようなものでしょう? 特に稼働中のシステムが Saga Persistence から RevenDb に移行しなければならない場合についてです。
Udi: NServiceBus では後方互換性の確保に,長期にわたって多大な努力を払ってきました。その結果,新しいバージョン上に構築された受信側プログラムと以前のバージョンの送信側プログラムを実行することも,その逆も可能になっています。さらに,以前のバージョンで管理されているタイムアウトを取得して,それを現行バージョンに転送する移行ツールを提供しています – すべてゼロ・ダウンタイムです。
長期間に渡って実行されるプロセス (NServiceBus では "Saga" と呼んでいます) に関しては,従来のバージョン (vLast) と並列に動作する新バージョン (vCurrent) の開発を推奨しています。新たに起動される長期実行プロセスが vCurrent エンドポイントとして開始され,その一方で vLast の旧プロセスが減少していく,というような方法です。ここでは NServiceBus パイプラインに組み込まれているメッセージの傍受機能が活用されています。vLast エンドポイントで新たなプロセスが起動されるのを防止しているのです。
ゼロ・ダウンタイムのアップグレードは,ユーザからも高い評価を受けてます。
InfoQ: 次期バージョンにはどのようなことが期待できるのでしょう?
Udi: ホスティング環境を改善して,複数のエンドポイントをひとつのプロセスで実行できるようにします。これによって大規模な統合シナリオにおける管理トポロジの拡大が実現できます。さらに (F# や Erlang のような) インメモリのメッセージ伝達プログラムモデルを C# の命令形式で利用したいと望む開発者のために,NServiceBus を単一プロセスにスケールダウンすることも検討しています。
私たちは昨年,NServiceBus 用の モデリングツール の準備版をいくつかリリースました。今年はその分野にも多額の投資を行うつもりです。ランタイムプロファイルの作成も視野に入れています。NSB Studio という名称で,メッセージベースおよびサービス指向システム用の完全なモデリング,開発,プロファイル統合環境です。
今後にご注目ください!