NServiceBus分发服务器吞吐量许可证限制或MSMQ性能地狱?

NServiceBus分发服务器吞吐量许可证限制或MSMQ性能地狱?,nservicebus,nservicebus-distributor,Nservicebus,Nservicebus Distributor,昨天,在与分销商进行了一些非常有希望的测试之后,我请求额外的预算来购买NSB(36-80核)的许可证 值得一提的是,我们目前正在使用分销商解决管道问题,但尚未用于真正的商业活动,但这将在稍后进行 今天,我的技术非常熟练的同事也开始使用该总线,只是由于他的项目的性质,他的性能要求比我的高出很多。因此,他的测试需要比分销商目前给我的平均30-50 msg pr秒多得多 无论我们试图做什么: 更多的工人 辅助线程上有更多线程 分配器上有更多线程 启用/禁用故障诊断码 所有这些都是在一个简单的概念验证设

昨天,在与分销商进行了一些非常有希望的测试之后,我请求额外的预算来购买NSB(36-80核)的许可证

值得一提的是,我们目前正在使用分销商解决管道问题,但尚未用于真正的商业活动,但这将在稍后进行

今天,我的技术非常熟练的同事也开始使用该总线,只是由于他的项目的性质,他的性能要求比我的高出很多。因此,他的测试需要比分销商目前给我的平均30-50 msg pr秒多得多

无论我们试图做什么:

  • 更多的工人
  • 辅助线程上有更多线程
  • 分配器上有更多线程
  • 启用/禁用故障诊断码
  • 所有这些都是在一个简单的概念验证设置中完成的,其中一条消息只包含一个id。 我们无法得到超过100个味精,仅次于工人
  • 这是非常糟糕的,因为我已经准备好申请更多的预算资金,如果我们不能很快获得更好的性能,我们必须放弃该项目,我们将面临一些严重的麻烦:S

    问题:

            var queuePrefix = ConvertFriendlyNameTo.QueueName(AppDomain.CurrentDomain.FriendlyName);
    
            return NServiceBus.Configure.With()
                .DefineEndpointName(queuePrefix)
                .Log4Net(ObjectFactory.GetInstance<IServiceBusLog>().Build())
                .StructureMapBuilder()
                .JsonSerializer()
                .AsMasterNode()
                .RunDistributorWithNoWorkerOnItsEndpoint()
                .MsmqTransport()
                .IsTransactional(true)
                .DisableTimeoutManager()
                .DisableSecondLevelRetries()
                .UnicastBus()
                .CreateBus()
                .Start(() => NServiceBus.Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
    
            var queuePrefix = ConvertFriendlyNameTo.QueueName(AppDomain.CurrentDomain.FriendlyName);
    
            return NServiceBus.Configure.With()
                .DefineEndpointName(queuePrefix)
                .Log4Net(ObjectFactory.GetInstance<IServiceBusLog>().Build())
                .StructureMapBuilder()
                .JsonSerializer()
                .EnlistWithDistributor()
                .MsmqTransport()
                .IsTransactional(true)
                .DisableTimeoutManager()
                .DisableSecondLevelRetries()
                .UnicastBus()
                .CreateBus()
                .Start(() => NServiceBus.Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
    
    我们当前使用的开发人员许可证是否有限制导致此限制,或者MSMQ是否存在严重的性能问题,如以下示例所述:

    我在nservicebus自己的网站上读了很多关于许可证的文章,但是没有明确说明开发者许可证的限制

    希望有人能帮我:)

    [更新]

    我回到了基础,并试图用NSB自己的代码示例ScaleOut重现问题,只需发送10000条消息,看看工人/分销商会如何反应。因此,我启动了分发服务器和两个工作人员(每个工作人员有100个线程),猜猜是什么问题再次出现。

  • 幸运的是,这表明我们没有完全错误地配置分发服务器/工作服务器设置
  • 不幸的是,这意味着我们与分销商之间仍然存在性能问题
  • 然后我想知道这是否真的是这样,并开始运行一些简单数量的线程,调整与分销商和工人的测试。经过一些尝试,我得到的吞吐量高达400-500味精公关秒的样本。以下是我的发现:

    观察结果/解决方案:

            var queuePrefix = ConvertFriendlyNameTo.QueueName(AppDomain.CurrentDomain.FriendlyName);
    
            return NServiceBus.Configure.With()
                .DefineEndpointName(queuePrefix)
                .Log4Net(ObjectFactory.GetInstance<IServiceBusLog>().Build())
                .StructureMapBuilder()
                .JsonSerializer()
                .AsMasterNode()
                .RunDistributorWithNoWorkerOnItsEndpoint()
                .MsmqTransport()
                .IsTransactional(true)
                .DisableTimeoutManager()
                .DisableSecondLevelRetries()
                .UnicastBus()
                .CreateBus()
                .Start(() => NServiceBus.Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
    
            var queuePrefix = ConvertFriendlyNameTo.QueueName(AppDomain.CurrentDomain.FriendlyName);
    
            return NServiceBus.Configure.With()
                .DefineEndpointName(queuePrefix)
                .Log4Net(ObjectFactory.GetInstance<IServiceBusLog>().Build())
                .StructureMapBuilder()
                .JsonSerializer()
                .EnlistWithDistributor()
                .MsmqTransport()
                .IsTransactional(true)
                .DisableTimeoutManager()
                .DisableSecondLevelRetries()
                .UnicastBus()
                .CreateBus()
                .Start(() => NServiceBus.Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
    
  • 分发服务器需要比1更多的线程,但不要太多。现在我正在运行2个线程。我正在启动
  • 如果im运行20或100个线程,那么worker通常具有相同的性能。因此,我没有增加线程的数量,而是增加了工人的数量,这就成功了
  • 如果分发服务器或辅助服务器上的线程数量太多,它们似乎会陷入MSMQ事务之争,相互阻塞,从而导致系统突然阻塞。我可以很容易地用ScaleOut示例和我自己的代码重现阻塞,但是基于我所读的文章,TX之战只是一个猜测,我不知道这就是正在发生的事情
  • 后续问题:

            var queuePrefix = ConvertFriendlyNameTo.QueueName(AppDomain.CurrentDomain.FriendlyName);
    
            return NServiceBus.Configure.With()
                .DefineEndpointName(queuePrefix)
                .Log4Net(ObjectFactory.GetInstance<IServiceBusLog>().Build())
                .StructureMapBuilder()
                .JsonSerializer()
                .AsMasterNode()
                .RunDistributorWithNoWorkerOnItsEndpoint()
                .MsmqTransport()
                .IsTransactional(true)
                .DisableTimeoutManager()
                .DisableSecondLevelRetries()
                .UnicastBus()
                .CreateBus()
                .Start(() => NServiceBus.Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
    
            var queuePrefix = ConvertFriendlyNameTo.QueueName(AppDomain.CurrentDomain.FriendlyName);
    
            return NServiceBus.Configure.With()
                .DefineEndpointName(queuePrefix)
                .Log4Net(ObjectFactory.GetInstance<IServiceBusLog>().Build())
                .StructureMapBuilder()
                .JsonSerializer()
                .EnlistWithDistributor()
                .MsmqTransport()
                .IsTransactional(true)
                .DisableTimeoutManager()
                .DisableSecondLevelRetries()
                .UnicastBus()
                .CreateBus()
                .Start(() => NServiceBus.Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
    
  • 现在该怎么办?我们应该用其他东西来取代MSMQ,还是这个问题是NSB内部的问题,可能会在以后的版本中进行优化/修复
  • 这是分销商的预期工作方式吗?也就是说,我们唯一的解决办法是解雇更多的工人
  • 同一端点上的多个工作线程(但与分发服务器运行的机器不同)是否会导致竞争的消费者情况,从而可能再次导致工作线程之间的MSMQ TX之争
  • 示例和我们自己的代码之间有一个重要的区别,我们已经禁用了Raven订阅存储,并且仅在MSMQ上运行,但据我所知,分发服务器不使用Raven db进行存储。我错了吗?这会是一个获得一些表现的地方吗
  • 我现在正在做一些分布式测试,看看在同一台机器上启动多个worker是否有问题,但与分发服务器不在同一台机器上。我希望这是可能的,而不必为每个工人设置单独的队列,因为我们已经准备好为工人订购额外的服务器,并且没有更多的预算

    到目前为止,我有点失望,我不能简单地增加一个工作线程的数量,从一个工作线程开始,然后扩展到更多的机器,每个机器都有一个工作线程。现在我被迫在一台机器上有多个工人:/

    如果我缺少分销商/员工的任何一点,请分享,因为这让我发疯:/

    [更新2]

    如果我在visual studio外部使用NServiceBus.Integration NServiceBus.Distributor/Worker和一个Worker运行ScaleOut示例,我可以获得4-500 msg/秒的吞吐量

    这是伟大的,但它不能解释我在我们自己的设置中做了什么错误,我们是自我托管。查看我们的配置,并告诉我是否有可疑之处:

    分销商:

            var queuePrefix = ConvertFriendlyNameTo.QueueName(AppDomain.CurrentDomain.FriendlyName);
    
            return NServiceBus.Configure.With()
                .DefineEndpointName(queuePrefix)
                .Log4Net(ObjectFactory.GetInstance<IServiceBusLog>().Build())
                .StructureMapBuilder()
                .JsonSerializer()
                .AsMasterNode()
                .RunDistributorWithNoWorkerOnItsEndpoint()
                .MsmqTransport()
                .IsTransactional(true)
                .DisableTimeoutManager()
                .DisableSecondLevelRetries()
                .UnicastBus()
                .CreateBus()
                .Start(() => NServiceBus.Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
    
            var queuePrefix = ConvertFriendlyNameTo.QueueName(AppDomain.CurrentDomain.FriendlyName);
    
            return NServiceBus.Configure.With()
                .DefineEndpointName(queuePrefix)
                .Log4Net(ObjectFactory.GetInstance<IServiceBusLog>().Build())
                .StructureMapBuilder()
                .JsonSerializer()
                .EnlistWithDistributor()
                .MsmqTransport()
                .IsTransactional(true)
                .DisableTimeoutManager()
                .DisableSecondLevelRetries()
                .UnicastBus()
                .CreateBus()
                .Start(() => NServiceBus.Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
    
    var queuePrefix=ConvertFriendlyNameTo.QueueName(AppDomain.CurrentDomain.FriendlyName);
    返回NServiceBus.Configure.With()
    .DefineEndpointName(队列前缀)
    .Log4Net(ObjectFactory.GetInstance().Build())
    .StructureMapBuilder()
    .JsonSerializer()
    .AsMasterNode()
    .RunDistributor WithNowWorkerOnitSendPoint()
    .MsmqTransport()
    .IsTransaction(真)
    .DisableTimeoutManager()
    .DisableSecondLevelRetries()
    .UnicastBus()
    .CreateBus()
    .Start(()=>NServiceBus.Configure.Instance.ForInstallationOn().Install());
    
    工人:<