版本预先3版的建议是在分发服务器旁边的群集上运行超时管理器作为独立进程。 (详见此处:http://support.nservicebus.com/customer/portal/articles/965131-deploying-nservicebus-in-a-windows-failover-cluster)。
在将超时管理器作为附属程序集包含之后,在向经销商扩展时使用它的正确方法是什么?
服务A的每个工作程序是否应该在启用超时管理器的情况下运行,或者只应将服务A的分发程序进程配置为运行服务A的超时管理器?
如果每个工作人员都运行它,他们是否共享相同的Raven实例来存储超时? (如果是这样,你如何确保两个或更多工人同时没有获得相同的过期超时?)
答案 0 :(得分:10)
请允许我自己清楚地回答这个问题。
经过大量的挖掘和AndreasÖhlund在NSB团队(http://tech.groups.yahoo.com/group/nservicebus/message/17758)的帮助后,对这个问题的正确回答是:
您有以下3个问题:
解决方法:
通过在分发服务器上包含此代码,自行启动分发服务器上的超时管理器:
class DistributorProfileHandler : IHandleProfile<Distributor>
{
public void ProfileActivated()
{
Configure.Instance.RunTimeoutManager();
}
}
如果您运行主配置文件,这不是问题,因为主节点上会自动启动超时管理器。
这不是设计的,并且会对超时存储和超时调度进行轮询。所有工作人员都会在“给我即将到来的MASTERNODE超时”的情况下对超时存储进行轮询。请注意,他们要求MASTERNODE超时,而不是W1,W2等等。因此,几个工作人员最终会同时从超时存储中获取相同的超时,从而导致与Raven的删除超时时发生冲突。
调度总是通过LOCAL .timouts / .timeoutsdispatcher队列进行,而它应该通过MasterNode / Distributor上的超时管理器的队列。
解决方法,您需要同时执行这两项操作:
a)禁用worker上的超时管理器。将此代码包含在您的员工中
class WorkerProfileHandler:IHandleProfile<Worker>
{
public void ProfileActivated()
{
Configure.Instance.DisableTimeoutManager();
}
}
b)重新对工作人员进行NServiceBus,以便在MasterNode / Distributor上使用.timeouts队列。
如果你不这样做,任何对工作者的RequestTimeout或Defer的调用将会因为你忘记配置超时管理器而异常死亡。将其包含在您的工作程序配置中:
<UnicastBusConfig TimeoutManagerAddress="{endpointname}.Timeouts@{masternode}" />
由于超时管理器直接将消息调度到工作者输入队列而不从分发服务器存储队列中的可用工作程序中删除条目,因此工作程序在处理超时后将错误的“就绪”消息发送回分发服务器。即使您已经修复了1和2,也会发生这种情况,如果从工作服务器上的本地超时管理器或分发服务器/ MasterNode上运行的超时管理器获取超时,则没有任何区别。结果是在工作人员处理的每个超时时,在分发服务器的存储队列中建立额外的条目。
解决方法: 使用NServiceBus 3.3.15或更高版本。
答案 1 :(得分:1)
在版本3+中,我们创建了一个主节点的概念,在其中托管所有卫星,如分发器,超时管理器,网关等。
主节点运行起来非常简单 - 您只需将/ master标志传递给NServiceBus.Host.exe进程,它就会为您运行所有内容。因此,从部署角度来看,您曾经部署过分发服务器,现在就部署主节点。