通过脚本在Microsoft群集中创建专用MSMQ队列

时间:2010-11-10 12:34:07

标签: msmq windows-server-2008-r2 cluster-computing

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

MessageQueue.Create(“。\ private $ \ myqueue”,false);

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

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

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

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

我的两个问题是: 1)有没有办法在集群的上下文中运行安装,这样在创建专用队列时,它实际上是在集群中创建队列?

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

4 个答案:

答案 0 :(得分:3)

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

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

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

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

    i.  SET _CLUSTER_NETWORK_HOSTNAME_={virtualname}

   ii.  SET _CLUSTER_NETWORK_NAME_={virtualname}

  iii.  Compmgmt.msc

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

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

即展开消息队列。

F。右键单击Private Queues,然后单击New,Private Queue。

克。验证Create in:是否为虚拟名称。

小时。在队列名称中:私有$ \字段放入队列名称,然后单击确定按钮。

我。关闭计算机管理。

这适用于Windows 2008 R2

答案 1 :(得分:2)

相同的解决方案来自Powershell(你还没有使用它???) 我正在研究这个问题一段时间,最近发现了这个帖子。

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

这是我最近一直在使用的示例脚本,它将创建私有队列并为其设置权限。在远程计算机上创建。我使用Win2k3服务器。

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)"

答案 2 :(得分:0)

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

SET _CLUSTER_NETWORK_HOSTNAME_=cluster_name
SET _CLUSTER_NETWORK_NAME_=cluster_name

适用于Windows Server 2003 R2。

答案 3 :(得分:0)

为了那些花费数小时搜索如何使用.NET MessageQueue实现这一点的可怜的灵魂(像我一样), 可以在集群MSMQ 上创建队列而无需 Powershell:

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的网站。您还想检查env变量值的用途.User,.Process和.Machine。请注意。如果相关进程是LOCALSYSTEM,则.Process-scoped更改将在重新启动计算机之前生效。