このセクションでは、キューに置かれた通信の背後にある一般的な概念と主要な概念について説明します。 以降のセクションでは、ここで説明するキューの概念が Windows Communication Foundation (WCF) でどのようにマニフェストされるかについて詳しく説明します。
基本的なキューの概念
分散アプリケーションを設計するときは、サービスとクライアント間の通信に適したトランスポートを選択することが重要です。 使用するトランスポートの種類には、いくつかの要因が影響します。 サービス、クライアント、トランスポート間の分離という重要な要素の 1 つは、キューに入ったトランスポートまたは TCP や HTTP などのダイレクト トランスポートの使用を決定します。 TCP や HTTP などのダイレクト トランスポートの性質上、サービスまたはクライアントが機能しなくなったり、ネットワークが失敗したりすると、通信が完全に停止します。 アプリケーションが動作するには、サービス、クライアント、およびネットワークが同時に実行されている必要があります。 キューに置かれたトランスポートは分離を提供します。つまり、サービスまたはクライアント間の通信リンクが失敗した場合、クライアントとサービスは引き続き機能します。
キューは、通信相手やネットワークで障害が発生した場合でも、信頼性の高い通信を提供します。 キューは、通信相手間で交換されたメッセージをキャプチャして配信します。 キューは通常、何らかの種類のストアによってサポートされます。これは揮発性または永続的な場合があります。 キューは、サービスに代わってクライアントからのメッセージを格納し、後でこれらのメッセージをサービスに転送します。 間接キューは、どちらかのパーティによる障害の確実な分離を提供するため、高可用性システムと切断されたサービスに推奨される通信メカニズムになります。 間接参照には、待機時間が長くなるコストが伴います。 待機時間 は、クライアントがメッセージを送信してからサービスがメッセージを受信するまでの時間遅延です。 つまり、メッセージが送信されると、そのメッセージがいつ処理される可能性があるかわからないことを意味します。 キューに入ったほとんどのアプリケーションは、待ち時間が長い場合に対処します。 次の図は、キューに入った通信の概念モデルを示しています。
キュー通信の概念モデル
実際には、キューは分散概念です。 そのため、パーティに対してローカルにすることも、両方の当事者に対してリモートにすることもできます。 通常、キューはサービスに対してローカルです。 この構成では、クライアントはリモート キューへの接続に依存して常に使用することはできません。 同様に、キューは、キューからのサービス読み取りの可用性とは無関係に使用できる必要があります。 キュー・マネージャーは、キューのコレクションを管理します。 他のキュー・マネージャーからキューに送信されたメッセージを受け入れる役割を担います。 また、リモート キューへの接続を管理し、それらのリモート キューにメッセージを転送する役割も担います。 クライアントまたはサービス アプリケーションで障害が発生した場合でもキューの可用性を確保するために、通常、キュー マネージャーは外部サービスとして実行されます。
クライアントは、キューにメッセージを送信するときに、メッセージをターゲット キュー (サービスのキュー マネージャーによって管理されるキュー) にアドレス指定します。 クライアント上のキュー・マネージャーは、メッセージを伝送 (または送信) キューに送信します。 伝送キューは、ターゲット・キューへの伝送用のメッセージを保管するクライアント・キュー・マネージャー上のキューです。 その後、キュー・マネージャーは、ターゲット・キューを所有するキュー・マネージャーへのパスを検索し、そのキューにメッセージを転送します。 信頼性の高い通信を確保するために、キュー・マネージャーは、データ損失を防ぐために、信頼性の高い転送プロトコルを実装します。 宛先キュー・マネージャーは、それが所有するターゲット・キュー宛てのメッセージを受け入れ、メッセージを保管します。 サービスはターゲット キューから読み取る要求を行い、その時点でキュー マネージャーはメッセージを宛先アプリケーションに配信します。 次の図は、4 つの当事者間の通信を示しています。
一般的なデプロイ シナリオでのキュー通信
したがって、キュー・マネージャーは、送信側と受信側が実際の通信に影響を与えずに個別に失敗できるように、必要な分離を提供します。 キューによって提供される余分な間接参照の利点により、複数のアプリケーション インスタンスが同じキューから読み取りを行えるので、ノード間の農業作業のスループットが向上します。 そのため、より高いスケールとスループットの要件を達成するためにキューが使用されているのは珍しいことではありません。
キューとトランザクション
トランザクションを使用すると、一連の操作をグループ化して、1 つの操作が失敗した場合にすべての操作が失敗するようにすることができます。 トランザクションを使用する方法の例として、個人が ATM を使用して、普通預金口座から当座預金口座に 1,000 ドルを転送する場合があります。 これには、次の操作が必要です。
普通預金口座から 1,000 ドルを引き出す。
1,000ドルを当座預金口座に入金します。
最初の操作が成功し、1,000 ドルが節約口座から取り消されたが、2 番目の操作が失敗した場合、1,000 ドルは既に節約口座から引き出されているため失われます。 アカウントを有効な状態に保つには、1 つの操作が失敗した場合、両方の操作が失敗する必要があります。
トランザクション メッセージングでは、メッセージをキューに送信し、トランザクションの下でキューから受信できます。 したがって、メッセージがトランザクションで送信され、トランザクションがロールバックされた場合、結果はメッセージがキューに送信されたことがないかのように見えます。 同様に、メッセージがトランザクションで受信され、トランザクションがロールバックされた場合、結果はメッセージが受信されたことがないかのように見えます。 メッセージは、読み取るキューに残ります。
待機時間が長いため、メッセージを送信するときに、メッセージがターゲット キューに到達するまでの時間を把握する方法も、サービスがメッセージを処理するのにかかる時間もわかりません。 このため、1 つのトランザクションを使用してメッセージを送信し、メッセージを受信し、メッセージを処理する必要はありません。 これにより、不確定な時間コミットされないトランザクションが作成されます。 クライアントとサービスがトランザクションを使用してキューを介して通信する場合、クライアントとサービスの 2 つのトランザクションが関係します。 次の図は、一般的なキューに入った通信におけるトランザクションの境界を示しています。
キャプチャと配信のための個別のトランザクションを示すキューに入れられた通信
クライアント トランザクションは、メッセージを処理して送信します。 トランザクションがコミットされると、メッセージは伝送キューに入ります。 サービスでは、トランザクションはターゲット キューからメッセージを読み取り、メッセージを処理して、トランザクションをコミットします。 処理中にエラーが発生した場合、メッセージはロールバックされ、ターゲット キューに配置されます。
キューを使用した非同期通信
キューは、非同期の通信手段を提供します。 キューを使用してメッセージを送信するアプリケーションは、キュー・マネージャーによって発生する待ち時間が長いため、受信側がメッセージを受信して処理するのを待つことができません。 メッセージは、アプリケーションが意図したよりもはるかに長い時間キューに残る可能性があります。 これを回避するために、アプリケーションはメッセージに Time-To-Live 値を指定できます。 この値は、メッセージが伝送キューに残る期間を指定します。 この時間の値を超えて、メッセージがまだターゲット キューに送信されていない場合は、メッセージを配信不能キューに転送できます。
送信者がメッセージを送信すると、送信操作からの戻り値は、メッセージが送信者の送信キューにのみ送信したことを意味します。 そのため、ターゲット キューへのメッセージの取得でエラーが発生した場合、送信側アプリケーションはそのことをすぐに認識できません。 このようなエラーをメモするために、失敗したメッセージは配信不能キューに転送されます。
メッセージがターゲット キューに到達できない、期限切れの時間To-Live など、エラーは個別に処理する必要があります。 そのため、キューに登録されたアプリケーションが 2 セットのロジックを記述することは珍しくありません。
メッセージを送受信する通常のクライアントおよびサービス ロジック。
失敗した送信または配信からのメッセージを処理するための補正ロジック。
以降のセクションでは、これらの概念について説明します。
Dead-Letter キュープログラミング
配信不能キューには、さまざまな理由でターゲット キューに到達できなかったメッセージが含まれています。 理由は、期限切れのメッセージから、ターゲット キューへのメッセージの転送を妨げる接続の問題まで多岐に及びます。
通常、アプリケーションはシステム全体の配信不能キューからメッセージを読み取り、問題の原因を特定し、エラーの修正やメッセージの再送信やメモなどの適切なアクションを実行できます。
有害メッセージ キューのプログラミング
メッセージがターゲット キューに送信されると、サービスはメッセージの処理に繰り返し失敗する可能性があります。 たとえば、アプリケーションがトランザクションのキューからメッセージを読み取り、データベースを更新すると、データベースが一時的に切断されている可能性があります。 この場合、トランザクションがロールバックされ、新しいトランザクションが作成され、メッセージがキューから再読み取りされます。 2 回目の試行は成功または失敗する可能性があります。 エラーの原因によっては、メッセージがアプリケーションへの配信に繰り返し失敗する場合があります。 この場合、メッセージは "有害" と見なされます。このようなメッセージは、有害処理アプリケーションで読み取ることができる有害キューに移動されます。