NServiceBus.Master配置文件执行期间的MasterNodeConfig行为

时间:2013-01-16 11:01:20

标签: nservicebus nservicebus3 nservicebus-distributor

我今天遇到了障碍。在我们的组织中,所有部署都由TFS Build完成。每个NSB主机组件由构建门户打包和部署的位置。当我们尝试使用NSB的Scale-Out功能时,我们必须使用Master和Worker配置文件安装相同的组件。我们管理了Master&工作者安装程序通过在打包时传递所需的参数。为了简化流程,我们计划为Master和Worker使用一个配置文件,我们为master和worker保留了MasterNode配置。一切都好!它运作得非常好。

根据策略,我们不应该在配置文件上使用服务器名称,我们必须在Config文件中使用DNS别名。我们通过在DNS别名之上启用MSMQ工作来实现它。

现在真正的问题开始了, NServiceBus.Master配置文件将Node值附加到输入队列中。当我们将DNS别名用作Node时,它会抛出以下异常。

  

System.Exception:启动端点时出现异常,错误已经发生   登录。原因:输入队列[somequeue@some-dns.bus]必须在   与此过程相同的机器[SOMEDITSERVER01]。 --->   System.InvalidOperationException:输入队列   [somequeue@some-dns.bus]必须与此过程位于同一台计算机上   [SOMEDITSERVER01]。在   NServiceBus.Unicast.Queuing.Msmq.MsmqMessageReceiver.Init(地址   地址,布尔事务处理)   NServiceBus.Unicast.Transport.Transactional.TransactionalTransport.NServiceBus.Unicast.Transport.ITransport.Start(地址   地址)   NServiceBus.Unicast.UnicastBus.NServiceBus.IStartableBus.Start(动作   在NServiceBus.Hosting.GenericHost.Start()

的startupAction      

---内部异常堆栈跟踪结束--- at   NServiceBus.Hosting.GenericHost.Start()at   Magnum.StateMachine.EventActionList`1.Execute(T stateMachine,Event   event,Object parameter)

     

---内部异常堆栈跟踪结束--- at   Magnum.StateMachine.ExceptionActionDictionary 1.HandleException(T stateMachine, Event event, Object parameter, Exception exception)
at Magnum.StateMachine.EventActionList
1.Execute(T stateMachine,Event   event,Object parameter)at   Magnum.StateMachine.State 1.RaiseEvent(T instance, BasicEvent 1   eevent,Object value)at   Magnum.StateMachine.StateMachine`1.RaiseEvent(Event raise)at   Topshelf.Internal.ServiceControllerProxy.Start()at   Topshelf.Internal.ServiceCoordinator.Start()at   Topshelf.Internal.Hosts.ConsoleHost.Run()at   NServiceBus.Hosting.Windows.Program.Main(String [] args)

问题:

为什么NSB将MasterNode值附加到输入队列&其他队列,当NSB严格查找当前MachineName作为当前输入队列的有效服务器名称时? 为什么NSB在使用NServiceBus.Master或NServiceBus.Distributor运行时忽略MasterNode值?

如果NSB仍想在输入队列上附加MasterNode值... 为什么NSB不解析DNS名称,而是使用当前MachineName进行验证?

var configSection = Configure.GetConfigSection<MasterNodeConfig>();
if (configSection == null)
{
    return;
}
var ipAddressesOfNode = Dns.GetHostEntry(configSection.Node).AddressList.Select(ip => ip.ToString()).ToArray();
var ipAddressesOfHost = Dns.GetHostEntry(Environment.MachineName).AddressList.Select(ip => ip.ToString()).ToArray();
if (ipAddressesOfHost.Any(ipAddressesOfNode.Contains))
{
    //Valid DNS Name
}

最后,我们最终得到以下选项,

1. 失败的方法:更改IHandleProfile上的MasterNodeConfig的Node值。我喜欢这种方法,但它有一些缺点。它不会工作,因为MasterNodeConfig没有覆盖IsReadonly()的默认行为,它会抛出错误。如果您使用集成配置文件,则在安装过程中不会创建Worker&amp;分销商队列

internal class MasterNodeConfigSetup : IHandleProfile<Master> 
{
public void ProfileActivated()
{
var configSection = Configure.GetConfigSection<MasterNodeConfig>();
configSection.Node = Environment.MachineName;
} 
}

有一种黑客可以绕过上面代码创建的运行时错误。但是如果你手动注意其他队列创建,我们可以使用它;

var field = typeof(ConfigurationElement).GetField("_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
if (field != null)
{
field.SetValue(configSection, false);
configSection.Node = Environment.MachineName;
}

2.保留两个不同的Config文件,用于worker和master&amp;打包它。很多工作看起来都很可行。

3.在主组件部署期间删除MasterNodeConfig。

我不反对NSB,我喜欢NSB。我只是表达了我的沮丧,想知道原因为什么!为什么它附加MasterNode值&amp;为什么它只是用Environemnt验证而不是解决它。

我非常愿意接受你的任何建议。

0 个答案:

没有答案
相关问题