【问题标题】:Creating a private MSMQ queue in a Microsoft Cluster via a script通过脚本在 Microsoft 集群中创建私有 MSMQ 队列
【发布时间】:2011-05-07 20:48:42
【问题描述】:

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

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

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

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

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

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

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

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

【问题讨论】:

  • 请仔细标记。删除不正确的标签cluster-analysis(又名:“集群”,与集群计算相反)

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


【解决方案1】:

这是在集群实例上手动执行此操作的方法。 (不是通过代码)

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

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

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

    i.  SET _CLUSTER_NETWORK_HOSTNAME_={virtualname}

   ii.  SET _CLUSTER_NETWORK_NAME_={virtualname}

  iii.  Compmgmt.msc

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

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

e。展开消息队列。

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

g.验证 Create in: 是虚拟名称。

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

我。关闭计算机管理。

这适用于 Windows 2008 R2

【讨论】:

    【解决方案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)"
    

    【讨论】:

    • 稍作修改的版本适用于 2019 和 New-MSMQQueue 以及此类 cmdlet,因此您无需回退到这些。您可以将它们与集群名称一起使用,您只需设置 2 个环境变量 - 将 $clusterName 替换为您的集群,然后所有 cmdlet 都应该可以正常工作 $env:computername = $clusterName $env:_CLUSTER_NETWORK_NAME_=$clusterName
    【解决方案3】:

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

    SET _CLUSTER_NETWORK_HOSTNAME_=cluster_name
    SET _CLUSTER_NETWORK_NAME_=cluster_name
    

    它适用于 Windows Server 2003 R2。

    【讨论】:

      【解决方案4】:

      为了那些花费数小时研究如何使用 .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 设置它们,之后也很难清除它们。此外,如果您尝试从机器 within 访问 cluster 中的 private 队列,似乎只需要设置环境变量em> 集群。

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

      【讨论】:

        猜你喜欢
        • 2011-06-16
        • 2014-12-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-30
        • 2011-03-20
        • 2011-04-21
        • 2014-07-22
        • 1970-01-01
        相关资源
        最近更新 更多