4

我们正在迁移到 Windows 2008 R2 Standard,并将使用 Microsoft 集群(主动-被动)配置。我们的应用程序严重依赖 MSMQ 私有队列,我们​​的安装使用以下 C# 代码创建了超过 100 个私有队列。

MessageQueue.Create(".\private$\myqueue", false);

由于安装不在集群上下文中运行,因此队列是在本地节点上创建的,而不是在集群中。

然后我们尝试将代码更改为:

MessageQueue.Create("MYCLUSTERNAME\private$\myqueue", false);

但是,您不能在不同的服务器(在本例中为集群服务器上下文)上创建专用队列,并且您会收到错误“无效的队列路径名”。

我的两个问题是:1)有没有办法可以在集群的上下文中运行安装,以便在创建私有队列时,它实际上会在集群中创建队列?

2) 如果不是,通过 .NET 在集群中创建队列的最佳方法是什么?我读过一些博客,其中人们创建了驻留在集群内的中间人 Windows 服务,然后他们的安装使用进程间通信来告诉服务要创建哪些队列。这似乎是一种 hack,但如果事实证明这是唯一的方法,这是可行的。

4

4 回答 4

3

以下是如何在集群实例上手动执行此操作。(不是通过代码)

仅在活动节点上,创建必要的 MSMQ 队列。

一个。单击开始,右键单击命令提示符,然后单击以管理员身份运行。

湾。在命令提示符中输入以下命令(其中 {virtualname} 是实例的名称。)

    i.  SET _CLUSTER_NETWORK_HOSTNAME_={virtualname}

   ii.  SET _CLUSTER_NETWORK_NAME_={virtualname}

  iii.  Compmgmt.msc

C。现在计算机管理已从与变量相同的命令提示符启动,看起来您是在本地进行更改,但实际上是在集群实例中更改它们。

d。展开服务和应用程序。

e. 展开消息队列。

F。右键单击专用队列,然后单击新建,专用队列。

G。验证 Create in: 是虚拟名称。

H。在 Queue name: private$\ 字段中输入队列名称,然后单击 OK 按钮。

一世。关闭计算机管理。

这适用于 Windows 2008 R2

于 2011-10-27T15:13:19.420 回答
3

Same solution From Powershell (what you aren't using it yet???) I was working on this problem for a while, found this thread recently.

http://winterdom.com/2011/10/using-powershell-with-clustered-msmq

Here's a sample script which I've been using recently that will create the private queues and set permission on it. Creates on remote machines. I work with Win2k3 servers.

Invoke-Command -ScriptBlock {
$env:_CLUSTER_NETWORK_NAME_ = 'myclusterMSMQ'

Write-Host "... load the .NET Messaging assembly"
[Reflection.Assembly]::LoadWithPartialName("System.Messaging")
$environment="perf2"
$groups=@{`
    "MessageRouters"="DomainName\Group";`
    "CalcDaemons"="DomainName\GroupB";`
    "MessageSenders"="DomainName\GroupC";`
}


function new-queue ([string] $queuepath,[bool] $transactional)
{
    if (([System.Messaging.MessageQueue]::Exists($queuepath))){throw "$queuepath already exists"}
    Write-Host "creating $queuepath"
    [System.Messaging.MessageQueue]::Create($queuepath,$transactional)
}

function set-msmqpermission ([string] $queuepath,[string] $account, [string] $accessright)
{
    if (!([System.Messaging.MessageQueue]::Exists($queuepath))){
        throw "$queuepath could not be found."
    }
    $q=New-Object System.Messaging.MessageQueue($queuepath)
    $q.SetPermissions($account,[System.Messaging.MessageQueueAccessRights]::$accessright,            
      [System.Messaging.AccessControlEntryType]::Set)
}

#example usage
new-queue ".\private$\$($environment)ack" $false
set-msmqpermission ".\private$\$($environment)ack" $groups.messagerouters "FullControl"

} -ComputerName "servername (or array)"
于 2012-06-29T20:48:27.213 回答
0

要解决您的问题,请尝试在运行应用程序之前设置两个环境变量:

SET _CLUSTER_NETWORK_HOSTNAME_=cluster_name
SET _CLUSTER_NETWORK_NAME_=cluster_name

它适用于 Windows Server 2003 R2。

于 2011-05-13T07:46:30.027 回答
0

为了那些花费数小时研究如何使用 .NET MessageQueue 来实现这一点的可怜人(像我一样),可以在没有Powershell的情况下在集群 MSMQ 上创建队列:

Environment.SetEnvironmentVariable("_CLUSTER_NETWORK_HOSTNAME_", "yourclustername", EnvironmentVariableTarget.User);
Environment.SetEnvironmentVariable("_CLUSTER_NETWORK_NAME_", "yourclustername", EnvironmentVariableTarget.User);

var path = @"yourclustername\Private$\yourprivatequeuepath";
MessageQueue.Create(path, false);

在服务器 2012 上测试。

警告:请注意设置环境变量,因为即使您使用 EnvironmentVariableTarget.User 设置它们,之后也很难清除它们。此外,如果您尝试从集群中的机器访问集群中的私有队列,似乎只需要设置环境变量。

如果您不小心设置了环境变量,您可以在 HKCU\Environment 的注册表中清除它们。可能出现的一个问题是,如果您在设置了环境变量的不同用户上下文中运行代码。在一种情况下,我能够以该用户身份登录,然后将它们从注册表中删除,但在另一种情况下,我正在调试 IIS 下的网站,并且 LOCALSYSTEM 帐户已设置它们。为了清除它们,我发布了一个将值设置为 null 的网站。您还想检查 .User、.Process 和 .Machine 的 env 变量值是什么。请注意,如果有问题的进程是 LOCALSYSTEM,则 .Process 范围的更改在重新启动机器之前不会生效。

于 2016-04-14T08:39:30.450 回答