あなたの仮定:
MSMQは別のサーバーでホストされると思います。
間違っている。MSMQは、メッセージキューに参加するすべてのマシンにインストールされます。
2つのWCFサービスがあります。1つは着信メッセージ用で、もう1つは発信メッセージ用です。
最も一般的な構成では、宛先キューはリスニングサービスに対してローカルです。
たとえば、ServiceAには、読み取り元のローカルキューがあります。ServiceBには、読み取り元のローカルキューもあります。ServiceAがServiceBを呼び出したい場合は、ServiceBのローカルキューにメッセージを入れます。
私は正しい構成で理解しています、それがトランザクションであることができるようにシステムを持つことができます(メッセージが失われることはありません)
正解です。これは、MSMQがストアアンドフォワードと呼ばれるメッセージングパターンを使用しているためです。説明については、こちらをご覧ください。
基本的に、メッセージの損失がないと想定しても安全な理由は、あるマシンから別のマシンへのメッセージの送信が実際には3つの異なるトランザクションの下で行われるためです。
- 最初のトランザクション:ServiceAはそれ自体の一時ローカルキューに書き込みます。これが失敗した場合、トランザクションはロールバックされ、ServiceAは例外を処理できます。
- 2番目のトランザクション:ServiceAマシンのキューマネージャーは、ServiceBマシンのキューマネージャーにメッセージを送信します。失敗した場合、メッセージは一時キューに残ります。
- 3番目のトランザクション:ServiceBはローカルキューからメッセージを読み取ります。ServiceBメッセージハンドラメソッドが例外をスローした場合、トランザクションはメッセージをローカルキューにロールバックします。
アプリケーション/サービスは、メッセージを処理するためにマルチスレッド化されます
メッセージ処理チェーンで順序を保持する必要がある場合を除いて、これは問題ありません。順序付けされた処理が必要な場合は、順序付けを再適用するための再シーケンサーを実装せずに複数のスレッドを作成することはできません。
MSMQを個別にホストして、x台のサーバーでそのキューを共有できると思いましたか?
メッセージの交換に参加したいすべてのサーバーには、MSMQがインストールされています。その後、各サーバーは他のサーバー上の任意のキューに書き込むことができます。
私が考えた理由は、サーバーがダウンした場合はどうなるのでしょうか。次に、メッセージはどのようにMSMQに送受信されますか
キューがトランザクションである場合、それはそれらのメッセージがディスクに永続化されることを意味します。サーバーがダウンした場合、サーバーが復旧してもメッセージはまだそこにあります。サーバーがダウンしている間は、明らかにメッセージの交換に参加できません。ただし、メッセージは引き続きそのサーバーに「送信」できます。宛先サーバーがオンラインに戻るまで、メッセージは送信者に対してローカルのままです(一時キュー内)。
したがって、中央のMSMQサーバーを1つ持つ(そしてミラーリング/フェイルオーバーする)ことで、稼働時間の保証が得られます。
メッセージキューを使用することの全体的なポイントは、フォールトトレラントなトランスポートであるため、稼働時間を保証する必要がないことです。100%の可用性がある場合、メッセージキューを使用する理由はほとんどありません。
着信メッセージはどのようにWCFに通知されますか?
各サービスは、独自のローカルキューでリッスンします。メッセージが到着すると、WCFランタイムにより、処理メソッドが呼び出され、メッセージが処理されます。
メッセージ送信の失敗はどのようにサービスに通知されますか
ServiceAがServiceBへのメッセージの送信に失敗した場合、ServiceBにその失敗が通知されることはありません。また、そうすべきではありません。ServiceAは、ServiceBではなく、送信の失敗を処理します。この場合の期待は、サービス間のハードカップリングを作成します。これは、メッセージキューによって削除されるはずです。