Windows フェールオーバー クラスターで「メッセージ キュー サービスは利用できません」

Windows フェールオーバー クラスターで「メッセージ キュー サービスは利用できません」

私は、メッセージ キューイング用の MSMQ クラスター グループを備えた 3 ノードのフェールオーバー クラスターでアプリケーションが実行されるサイトでデバッグを行っています。システムは一部のノードの組み合わせでは動作しますが、すべてのノードの組み合わせでは動作しないため、フェールオーバー セキュリティは意図したほど良好ではありません。

問題は、クラスター化されたキューからメッセージを受信するときに発生します。

アプリケーションがクラスター ノード B または C で実行される場合、MSMQ がどのノードで実行されているかに関係なく、アプリケーションは動作します (動作する = アプリケーションはメッセージを受信します)。アプリケーションがノード A で実行される場合、MSMQ がどこで実行されているかに関係なく、メッセージ キュー サービスが利用できないためにアプリケーションは失敗します。

さらに混乱を招くように、GUI クライアントを備えた小さな WCF-MQ プロキシ サービスを作成しました。これにより、サービスにコマンドを送信でき、サービスがクライアントの指定に従ってメッセージ キューとの間で送受信を行い、そのプロセスで可能な限り多くのフィードバックを提供します。このアプリのパターンは同じですが、MSMQ がどこで実行されているかに関係なく、失敗するノードはノード C です。

私が確認した点のいくつかを以下に示します。

  • サービス (当社のアプリ) は、3 つのノードすべてで同じドメイン ユーザー アカウントで実行されます。
  • アプリ構成ファイルには、メッセージ キューへの同じパスが含まれています。
  • キューのアクセス権: 全員が完全な制御権を持ちます。
  • ローカル MSMQ サービスはすべてのノードで実行されており、ローカル キューの名前がクラスター化されたキューの名前と同じではないことを確認しました。
  • すべてのノードでファイアウォールが無効になっています。
  • ノード A は、クラスター ネットワークと同じサブネット上に追加のネットワーク接続がある点で、B および C とは異なります。そのため、ノード B から ping を実行すると、「間違った」インターフェイスで応答します。問題になるかどうかはわかりませんが、少し奇妙です。
  • サービス オプション「マシン名にネットワーク名を使用する」では何も変更されないようです。プロキシ サービスは認識されたマシン名を報告し、ノード A では常にクラスター グループ名を返し、ノード B と C では常にノード名を返します。
  • MSMQ クラスター グループは、ストレージに共有 iSCSI ドライブを使用します。

私は単なる開発者であり、決して Microsoft インフラストラクチャの専門家ではないので、質問したいのですが、このようなクラスター化された MSMQ セットアップをデバッグするときに推奨される手順は何ですか?

答え1

さて、数週間にわたって私自身と Microsoft のメッセージ キュー サポート チームと協力してデバッグした結果、解決策が見つかりました。

TLDR; 解決策はレジストリキーを削除するか名前を変更することです

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\<SERVICENAME>\Environment

エラーの原因は、MQ クライアントがローカル システムで MQ サービスを見つけられないことです。これは、リモート MQ との通信に必要です。これは、電子メールをリモート システムに転送するローカル SMTP サービスに似ています。ただし、この場合、ローカル システムはクラスター ノードではなく、「クラスター グループ」であり、クラスター グループでは MQ サービスが実行されていません (実際のシステムではなく、単なるエイリアスであるため)。MQ クライアントがクラスター グループでサービスを探す理由は、クラスター サービス設定で [コンピューター名にネットワーク名を使用する] チェック ボックスがオンになっているためです。これにより、クラスター ノードのレジストリに新しい値が追加され、サービスの環境が設定されます。実際の問題は、このチェック ボックスをオフにしてもレジストリから値が削除されず、いったん設定すると、(GUI から) 設定を適切にクリアできなくなることです。したがって、修正するには、regedit または regedt を使用して手動で値を削除します。

関連情報