NServiceBus分销商吞吐量许可限制或MSMQ性能地狱?

时间:2013-03-22 23:03:25

标签: nservicebus nservicebus-distributor

昨天,在经销商进行了一些非常有希望的测试后,我要求额外预算购买NSB(36-80芯)的许可证。

应该提到的是,我们目前正在使用经销商来解决管道问题而尚未用于真正的商务活动,但这是后来的事。

今天,我非常熟练的同事也开始使用公共汽车,由于他的项目性质,他的性能要求比我的高很多。因此,他的测试需要比经销商目前给我的平均30-50 msg pr平均值更多。

无论我们试图做什么:

  1. 更多工人。
  2. 关于工人的更多主题。
  3. 经销商处有更多主题。
  4. 启用/禁用DTC
  5. 以上所有内容均采用裸骨概念验证设置,并带有仅带有id的消息。 我们无法获得大约100 msg分布式pr。第二个是工人。
  6. 这非常糟糕,因为我已经申请了更多的预算资金,如果我们不能很快获得更好的表现,我们就不得不放弃这个项目,我们将面临一些严重的麻烦:S。

    问题:

    我们当前使用的开发人员许可证是否存在限制,导致此限制或MSMQ存在严重的性能问题,例如此处所述:http://ayende.com/blog/4251/what-am-i-missing-msmq-perf-issue

    我已经在nservicebus自己的网站上阅读了很多关于许可证的内容,但没有明确描述开发者许可证的限制。

    希望有人可以帮助我:)。

    [UPDATE]

    我回到基础并尝试用NSB自己的代码示例 ScaleOut 重现问题,只需发送10000条消息,看看工人/经销商会如何反应。所以我开始了经销商和2名工人(工人每人有100个线程)并猜测重新出现的问题。

    1. 幸运的是,这表明我们尚未完全错误地配置我们的分销商/工作人员设置。
    2. 不幸的是,这意味着我们仍然存在分销商的性能问题。
    3. 然后我想知道这是否真的如此,并开始运行一些简单的线程数,调整与Distributor和Workers的测试。经过一些尝试,我的样品中的吞吐量高达400-500 msg pr sec。这是我发现的:

      观测/解决方案:

      1. 分销商需要的线程多于1,但不是太多。现在我正在运行2个线程pr。工人我启动。
      2. 如果运行20或100个线程,工作人员通常会有相同的性能。因此,我没有提高线程的数量,而是提高了工作人员的数量,这就是诀窍。
      3. 如果分销商或工作人员的线程数太高,他们似乎会遇到 MSMQ事务战,在那里他们互相阻塞,从而使系统突然堵塞。我可以使用ScaleOut示例和我自己的代码轻松地重现障碍物,但TX战斗只是基于我读过的文章的一个疯狂的猜测,我没有说明这就是正在发生的事情。
      4. 后续问题:

        1. 现在该怎么办?我们应该用其他东西替换MSMQ,还是这个问题是NSB内部的问题,可以在以后的版本中进行优化/修复?
        2. 这是分销商工作的预期方式吗,这意味着我们唯一的解决办法是解雇更多工人?
        3. 同一个端点上的多个工作人员,但是与分发服务器运行的机器不同,不会导致竞争消费者情况,这可能会再次导致工人之间的MSMQ TX战斗?
        4. 示例和我们自己的代码之间有一个重要的区别,我们已禁用Raven订阅存储并且纯粹在MSMQ上运行,但据我所知,分发服务器不使用Raven db进行存储。我错了,这可能是一个获得一些表现的地方吗?
        5. 我现在正在做一些分布式测试,看看是否在同一台机器上启动多个工作人员,但与分发服务器不同的机器。我希望不必为每个工作人员设置单独的队列,这是可能的,因为我们已经为工作人员订购了额外的服务器而且没有更多的预算。

          到目前为止,我有点失望的是,我不能简单地调出一个工作线程的线程数,只从一个工作开始,然后扩展到更多的机器,每个机器有1个工人。现在我被迫在一台机器上安装了多个工作人员:/。

          如果关于经销商/工作人员遗失的任何小问题,请分享,因为这让我发疯:/。

          [更新2]

          如果我使用NServiceBus.Integration NServiceBus.Distributor / Worker和只有1名工作人员在visual studio外部运行ScaleOut示例,我可以获得4-500 msg / sec的吞吐量。

          这很好,但它没有解释我在自己的设置中做错了什么我们自己托管。看看我们的配置,告诉我是否有些可疑:

          发行者:

                  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());
          

          我们在这里做错了什么可能导致性能差异?

          亲切的问候。

0 个答案:

没有答案