メッセージキュー
メッセージキュー(Message queue)は、プロセス間通信や同一プロセス内のスレッド間通信に使われるソフトウェアコンポーネントである。制御やデータを伝達するメッセージのキューである。
メッセージキューは非同期型通信プロトコルの一種を提供しており、送信側と受信側がメッセージキューに同時にやり取りしなくともよいことを意味する。キューに置かれるメッセージは、受信側がそれを取り出すまで格納されたままとなる。メッセージキューは大抵の場合、格納できる1つのメッセージの大きさや保持できるメッセージ数に上限を設けている。
メッセージキューには様々な実装がある。オペレーティングシステム内に実装される場合やアプリケーションソフトウェア内に実装される場合がある。それらのキューはそのシステムが必要とする用途でのみ使われる。
その他の実装では、コンピュータ間のメッセージのやり取りに使われたり、複数のアプリケーションや複数のオペレーティングシステム間の接続に使われたりする。このようなメッセージキューシステムでは、システムの障害が発生してもメッセージを無くしたりしないような「回復力; resilience」のある機能が提供されることが多い。この種のメッセージキューを実装した商用ソフトウェア(メッセージ指向ミドルウェアとも呼ぶ)として、IBM の WebSphere MQ、オラクルの Oracle Database に含まれる Oracle Advanced Queuing (AQ)、マイクロソフトの Microsoft Message Queuing、日立製作所のTP1/MessageQueue、セゾン情報システムズの などがある。Java の関連する標準として Java Message Service があり、これにはオープンソースのものもプロプライエタリのものも含めていくつかの実装がある。
メッセージ関連のミドルウェアシステムとして、いくつかのオープンソースのものがある。例えば、、、Apache ActiveMQ、Apache Qpid、RabbitMQ、 、Mule、OpenMQなどである。
VxWorksやQNXといったリアルタイムオペレーティングシステム (RTOS) では、メッセージキューを主要なプロセス間通信機構やスレッド間通信機構として採用している。これらの場合、リアルタイム性が重視されるため、メッセージキューとCPUスケジューリングが密に関連している。1980年代初期には、VRTX や pSOS+ といった RTOS でメッセージキューを使ったスレッド間通信機構が使われ始めた。
典型的なメッセージキューの実装では、システムアドミニストレータがメッセージキューソフトウェア(キューマネージャ)をインストール・設定し、名前のついたメッセージキューを定義する。アプリケーションは、そのキューにメッセージが置かれるのを待つソフトウェアルーチン(リスナー)を登録する。別の(複数の)アプリケーションがそのキューに接続し、メッセージをそこに転送する。キューマネージャは受信側アプリケーションが接続するまでメッセージを蓄積しておき、接続した時点で登録されたソフトウェアルーチンを呼び出す。受信アプリケーションは適切な方法でメッセージを処理する。
これには様々なバリエーションが存在する。例えば、次のような点である。
永続性(キューをメモリ上に置くか、ディスク上に置くか。さらに安全性を高めるためにDBMSに置くこともある)
セキュリティポリシー - メッセージへのアプリケーションのアクセス権の認証
メッセージ消去ポリシー - キューやメッセージに生存時間 (time to live) が設定される場合がある。
システムによってはデータのフィルタリングをサポートしており、受信側は事前に設定した基準に合致したメッセージだけを受け取る。
配布ポリシー - 1つのメッセージが少なくとも1度配布されることを保証するか、それとも複数回配布されないことを保証するか。
ルーティングポリシー - キュー(サーバ)が複数存在する場合、それらの間のメッセージの受け渡しをどうするか。
バッチポリシー - メッセージは即時に配布されるか。それとも、短時間待って溜まったメッセージを1度に配布するか。
メッセージが「エンキュー; enqueue」されたというのはどういう場合を指すか。どこかのキューに置かれた場合全てを指すか。それとも、少なくとも1つのリモートのキューに置かれた場合を指すか。あるいは、全てのキューに置かれた場合を指すか。
送信側は(一部あるいは全部の)受信側がメッセージを受け取ったことを知る必要があるかどうか。
これらは、システムとしての意味論、信頼性、効率などを具体的にどうするかといった設計上の考慮すべき点である。
歴史的には、メッセージキューはプロプライエタリな閉鎖的プロトコルとして使われ始めたもので、そのために異なるOSやプログラミング言語を含めた環境の構築が制限されていた。
メッセージキューをより遍在的にする初期の試みとして、サン・マイクロシステムズのJMS仕様があり、JavaによってクライアントAPIを抽象化して異機種間接続を可能にしていた。これによりJavaを使えばメッセージキューのプロバイダーを切り替え可能となっており、SQLによってデータベースの切り替えが可能になったのと似ている。しかし実際にはメッセージキューの技法やシナリオは非常に多様であり、JMSが常に有効というわけではない。
その後、メッセージキューをオープンで遍在的なものにすべく以下の3つの標準が生まれている。
これらの標準化や採用の段階はそれぞれ異なる。いずれもHTTPと同じレベルで運用される。
プロプライエタリな実装でもHTTPを使ってメッセージキューを提供している場合があり、例えばAmazonのSQSがある。これは、要求-応答型の同期プロトコルの上で(メッセージキューに必要とされる)非同期動作の層を構築することが可能なためである。しかし、そのような実装は下層のプロトコルに制限され、上述したようなメッセージキューのあらゆるオプションを提供できない可能性がある。
多くの通信プロトコルは、同期型である。World Wide WebやWebサービスで使われている HTTP などは明らかに同期型である。同期モデルでは、あるシステムが別のシステムとのコネクションを形成し、要求を送って、応答を待つ。多くの場合、これで全く問題ない。例えば、ユーザーが Web ページに要求を送り、応答を待つというような場合である。
しかし、このようなシナリオではうまくいかない場合がある。例えば、AJAX (Asynchronous Javascript and XML) は非同期にテキストやXMLを送って、ウェブページの一部をより適切な情報で更新する。Googleは機能でこの方式を採用しており、検索ボックスにキーワードの一部を入力した際に考えられるキーワード全体の一覧を提供する。この一覧はユーザーの入力に従って非同期に更新される。
他の非同期な例として、イベント通知システムや出版-購読型システムがある。
あるアプリケーションが別のアプリケーションにイベント発生を知らせたいが、その応答を待つ必要がない(あるいは待てない)場合
出版-購読型モデルのシステムでは、アプリケーションは情報を任意の(不明な個数の)受信者に対して「出版」する。
これらの場合、例えば情報の受け手がクラッシュしてしまっている可能性もあり、送信側が応答を待つのは適切ではない。
アプリケーションは同期または非同期のどちらか一方だけで実装する必要はない。対話型アプリケーションは特定の要求に対して即座に応答する必要があるだろう(顧客に対して、在庫を確認したうえで購入要求が受理されたことを知らせる場合など)。しかし一方で、キューを使って処理を遅延させることが可能な部分もある(請求金額の計算を完了させ、そのデータを中央のデータベースに登録し、関連する他のサービスを実行する)。このような場合に、非同期型のメッセージキューを使えば、システム全体の性能(特に顧客から見た応答性能)を向上させることができる。