コンピュータサイエンスにおいて、メッセージキューとメールボックスはソフトウェアエンジニアリングの コンポーネントであり、通常はプロセス間通信(IPC)または同一プロセス内のスレッド間通信に使用されます。これらは、 制御またはコンテンツの受け渡しである メッセージングにキューを使用します。グループ通信システムも同様の機能を提供します。
メッセージキューパラダイムはパブリッシャー/サブスクライバーパターンの兄弟分であり、通常はより大規模なメッセージ指向ミドルウェアシステムの一部です。ほとんどのメッセージングシステムは、 APIにおいてパブリッシャー/サブスクライバーモデルとメッセージキューモデルの両方をサポートしています(例:Java Message Service (JMS))。
競合コンシューマーパターンは、複数の同時コンシューマーが同じメッセージキュー上のメッセージを処理することを可能にします。[1]
メッセージキューは、 2つ以上のプロセス/スレッド間の非同期通信パターンを実装します。これにより、送信側と受信側は同時にメッセージキューを操作する必要がありません。キューに配置されたメッセージは、受信者が取得するまで保存されます。メッセージキューには、1つのメッセージで送信できるデータのサイズと、キューに残されるメッセージの数に、暗黙的または明示的な制限があります。[2]
メッセージキューの実装の多くは、オペレーティングシステムまたはアプリケーション内部で機能します。このようなキューは、そのシステムのみを目的として存在します。[3] [4] [5]
他の実装では、異なるコンピュータシステム間でのメッセージの受け渡しが可能で、複数のアプリケーションや複数のオペレーティングシステムを接続することも可能である。[6] これらのメッセージキューイングシステムは通常、システム障害発生時にメッセージが「失われる」ことを防ぐためのレジリエンス機能を提供する。この種のメッセージキューイングソフトウェア(メッセージ指向ミドルウェアとも呼ばれる)の商用実装の例としては、IBM MQ (旧称MQシリーズ)やOracle Advanced Queuing(AQ)などがあげられる。Java標準にはJava Message Serviceがあり、これには複数のプロプライエタリソフトウェアとフリーソフトウェアの実装が存在する。
VxWorksやQNXなどのリアルタイムオペレーティングシステム(RTOS)では、プロセス間またはスレッド間通信の主要なメカニズムとしてメッセージキューの使用が推奨されています。これにより、メッセージパッシングとCPUスケジューリングの統合が可能になります。スレッド間通信にメッセージキューベースを採用した初期の商用RTOSの例としては、VRTXやpSOS +などが挙げられます。どちらも1980年代初頭に登場しました。Erlangプログラミング言語は、プロセスを用いて並行処理を実現します。これらのプロセスは、メッセージキューを用いて非同期通信を行います。
メッセージキューソフトウェアは、プロプライエタリ、オープンソース、またはその両方の組み合わせのいずれかです。オンプレミスのプライベートサーバー、または外部のクラウドサーバー(メッセージキューサービス)で実行されます。
ハードウェアベースのメッセージング ミドルウェアベンダーの例としては、 Solace、Apigee、IBM MQなどがあります。
典型的なメッセージキューイングの実装では、システム管理者はメッセージキューイングソフトウェア(キューマネージャーまたはブローカー)をインストールして設定し、名前付きメッセージキューを定義します。あるいは、メッセージキューイングサービスに登録します。
次に、アプリケーションは、キューに配置されたメッセージを「リッスン」するソフトウェア ルーチンを登録します。
2 番目以降のアプリケーションはキューに接続し、そこにメッセージを転送することができます。
キューマネージャソフトウェアは、受信側アプリケーションが接続し、登録されたソフトウェアルーチンを呼び出すまでメッセージを保存し、受信側アプリケーションは適切な方法でメッセージを処理します。
メッセージ パッシングの正確なセマンティクスに関しては、次のような多数のオプションが存在します。
これらはすべて、トランザクションのセマンティクス、システムの信頼性、およびシステムの効率に大きな影響を与える可能性のある考慮事項です。
歴史的に、メッセージ キューイングでは独自のクローズド プロトコルが使用されており、異機種混合の環境内で異なるオペレーティング システムやプログラミング言語が対話する能力が制限されていました。
メッセージキューイングをより普及させるための初期の試みは、Sun MicrosystemsのJMS仕様でした。これは、クライアントAPIのJava専用の抽象化を提供しました。これにより、Java開発者はSQLデータベースを使用する開発者と同様の方法で、メッセージキューイングのプロバイダを切り替えることができました。しかし実際には、メッセージキューイングの技術とシナリオの多様性を考えると、これは必ずしも実用的ではありませんでした。
オープンソースのメッセージ キュー実装で使用される 3 つの標準が登場しました。
これらのプロトコルは、標準化と採用の段階が異なります。最初の2つはHTTPと同じレベルで動作し、MQTTはTCP/IPと同じレベルで動作します。
AmazonのSQSなど、一部の独自実装でもHTTPを用いてメッセージキューイングを提供しています。これは、リクエスト/レスポンスセマンティクスを用いた同期プロトコル上に、非同期動作(メッセージキューイングに必要な動作)を常に重ねることができるためです。しかし、このような実装は基盤となるプロトコルによって制約を受け、上記のメッセージパッシングに必要な完全な忠実度やオプションセットを提供できない可能性があります。
現在広く使用されている通信プロトコルの多くは同期的に動作します。ワールドワイドウェブやウェブサービスで使用されるHTTPプロトコルは、 ユーザーがウェブページへのリクエストを送信し、応答を待つという分かりやすい例です。
しかし、同期動作が適切ではないシナリオも存在します。例えば、AJAX(Asynchronous JavaScript and XML)を使用すると、テキスト、JSON、またはXMLメッセージを非同期に送信し、ウェブページの一部をより関連性の高い情報で更新することができます。Google はこのアプローチをGoogleサジェストに採用しています。Googleサジェストは、ユーザーが部分的に入力したクエリをGoogleのサーバーに送信し、ユーザーが入力中に関心を持つ可能性のある完全なクエリのリストを返す検索機能です。このリストは、ユーザーの入力に合わせて非同期的に更新されます。
その他の非同期の例としては、イベント通知システムやパブリッシュ/サブスクライブシステムなどがあります。
上記の両方の例において、たとえば受信者の 1 人がクラッシュした場合、情報の送信者が待機する必要があるのは意味がありません。
アプリケーションは同期型か非同期型かだけに限定されるわけではありません。対話型アプリケーションでは、リクエストの特定の部分(販売リクエストが承認されたことを顧客に通知する、在庫を引き出す約束を処理するなど)には即座に応答する必要がありますが、他の部分(請求額の計算の完了、中央会計システムへのデータの転送、その他各種サービスの呼び出しなど)はキューに入れて後で実行する必要があります。
これらすべての状況では、メッセージ キューイング (またはブロードキャスト メッセージング システム) を実行するサブシステムを使用すると、システム全体の動作を改善することができます。
UNIXには2つの一般的なメッセージキュー実装があります。1つは SYS V API の一部であり、もう1つはPOSIXの一部です。
UNIX SYS Vは、リンクリストの配列をメッセージキューとして保持することでメッセージパッシングを実装しています。各メッセージキューは配列内のインデックスによって識別され、一意の記述子を持ちます。指定されたインデックスには複数の記述子を持つことができます。UNIXは、メッセージパッシング機能にアクセスするための標準関数を提供しています。[7]
msgget()IPC_CREATフラグが設定されている場合は、指定されたキーを持つ新しいメッセージキューを作成し、その記述子を返します。msgrcv()msgctl()IPC_RMIDフラグを渡すことでメッセージキューを削除することです。メッセージキューを削除できるのは、作成者、所有者、またはスーパーユーザーのみです。POSIX.1-2001 メッセージキュー API は、UNIX の 2 つのメッセージキュー API のうち、後者のものです。SYS V API とは異なりますが、同様の機能を提供します。UNIX のマニュアルページには、mq_overview(7)POSIX メッセージキューの概要が記載されています。
グラフィカルユーザーインターフェース(GUI)は、マウスクリック、キーボードイベント、その他のユーザー入力などのグラフィカル入力アクションをアプリケーションプログラムに渡すために、イベントキューまたは入力キューとも呼ばれるメッセージキューを使用します。[9]ウィンドウシステムは、タイマーの刻みや他のスレッドから送信されたメッセージなど、ユーザーイベントやその他のイベントを示すメッセージをメッセージキューに格納します。GUIアプリケーションは、イベントループ内で呼び出されるルーチンまたは同様のルーチンを呼び出すことで、これらのイベントを1つずつ削除し、その後、そのイベントを処理するための適切なアプリケーションルーチンを呼び出します。[10]getNextEvent()