AP4R,Rubyで非同期メッセージング

第1回 軽量さと堅牢さを兼ね備えたメッセージング

この記事を読むのに必要な時間:およそ 5 分

SAF(Store and Forward)機能とは

非同期処理を利用する際には,常に「失敗」した場合を考慮しておく必要があります。

ここでの失敗とは,メッセージングを行うプロセスの内部で起きるものだけでなく,ネットワークの切断によるエラー,データベースプロセスが突然死んだり,応答しなくなるといった外部の要因も含みます。

失敗しても非同期処理を保証するために,AP4Rでは,SAFという機能を提供しています。

以下,メッセージングの信頼性の一般的な話をした後,SAFが何を保証するのかを説明します。

メッセージの生成,保存,そして処理を確実に行うには何が必要?

メッセージのライフサイクルを見てみると,生成,保存,処理というステップがあることが分かります。

この流れを見ながら,確実に処理が行われるために必要なことを考えてみましょう。

図8 典型的なシーケンス その1:生成から保存まで

図8 典型的なシーケンス その1:生成から保存まで

図9 典型的なシーケンス その2:処理

図9 典型的なシーケンス その2:処理

まず「生成」について考えてみましょう。

一般に何らかの業務処理(業務データベースの更新処理)と結び付いています。

例えば,注文受付処理のなかで,注文を業務データベースに保存し,決済処理のメッセージを生成する場合を考えてみましょう。この2つのデータは,どちらか一方のみが欠けてしまうと問題が発生します。つまりアトミックである必要があるのです。

業務DBとメッセージDBが異なっていると,2つのDBでのコミットタイミングの違いにより,図8の赤い矢印のタイミングでエラーが発生すると,アトミック性が壊れる可能性があります。

注)
この文書のなかでは,以下の単語を特殊な意味で使います。
業務処理
メッセージングとは直接関係しない処理。⁠例)オンライン店舗での「注文受付処理」
業務データベース,業務DB
業務処理にもちいるデータベース
メッセージデータベース,メッセージDB
メッセージングのサービスが,メッセージを保存するために使うデータベース

次に「保存」についてです。生成はアプリケーションを処理するプロセスのなかに閉じていますが,保存はメッセージングのプロセスとの通信を伴います。

メッセージングでの保存がデータベースを利用した場合,メッセージDBのトランザクションが正常に完了した後に通信が失敗する,という隙間(図8の青い矢印)でのエラーを考慮する必要が生じます。

最後のステップである「処理」について細かく見てみると,メッセージの取得,業務 DB の更新,処理の完了通知という流れになっています。

ここでも,業務DBのトランザクションの完了から,通信の完了の隙間(図9の青い矢印)が存在します※1⁠。

アトミック性の保証,隙間で発生するエラーを考慮し,確実な処理を行うための仕組みを利用する必要があります。

※1
もうひとつ,メッセージングでのトランザクションも存在しますがここでは触れません。

ProducerとChannelの間の「最低でも1回(at-least-once)」

メッセージングに関わる2種類の言葉を紹介します。

まず,メッセージングで登場する3つの役割です。この説明は,かなり大まかなものですので,詳しくは,Enterprise Integration Patterns等を参照してください。

Producer
メッセージを生成して,Channelに送信します。図では,同期処理を行うRailsプロセスがこれにあたります。
Channel
メッセージの保存を行います。図では,AP4RサーバがChannelを管理しています。
Consumer
メッセージを,Channelから取得し処理します。図では,非同期リクエストを受ける Rails プロセスになります。

もうひとつは,⁠サービスの質(Quality of Service,QoS⁠⁠」のなかで,信頼性のあるメッセージング(Reliable Messaging)のレベルです。

信頼性のあるメッセージングに関するQoSには以下の3種類があります。

at-most-once
最大でも1回しか処理されないことを保証します。ただしメッセージが失われ,処理が行われない可能性はあります。
at-least-once
最低でも1回は処理が行われることを保証します。
once-and-only-once
上のふたつを合わせたもので,メッセージは必ず1回配信されることを保証します。

非同期メッセージングでの QoS については,KLab Architect Blogの記事「Requirments for Software Engineers」が参考になります。

単純なat-most-onceのみを保証することは,⁠隙間」でエラーが発生した場合にメッセージを廃棄すれば良く,比較的容易です。また,once-and-only-onceをメッセージングのみで保証することは,高い実行コストや,Producer/Consumerに対する制限につながることがあります。

著者プロフィール

加藤究(かとうきわむ)

フューチャーアーキテクト株式会社,シニアコンサルタント。土木専攻だった大学時代には,道路や橋の建設について学んできたが,社会に出てからは Javaのメッセージングミドルウェアの開発/保守などに従事。昨年,Rubyで書いたメッセージングライブラリ,AP4Rでオーンソースの世界に仲間入り。現在は,AP4Rの開発/導入サポート中。

URLhttp://d.hatena.ne.jp/kiwamu/


篠原俊一(しのはらしゅんいち)

フューチャーアーキテクト株式会社,シニアコンサルタント。大学時代は物理学を専攻,素粒子論を研究,10次元の世界に住んでいた。入社後まもなく,Martin FowlerのblikiでRubyを知り,"The Ruby Way"に学ぶ。 Rubyとオープンソースが大好きなプログラマとして,AP4Rを開発中。

URLhttp://d.hatena.ne.jp/ita-wasa/