2

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

应该提到的是,我们目前正在使用分销商来解决管道问题,而不是真正的商业活动,但这将在以后出现。

今天我非常熟练的同事也开始使用公共汽车,只是由于他的项目性质,他的性能要求比我高得多。所以他的测试需要比分销商目前给我的平均 30-50 msg pr 秒多得多。

无论我们尝试做什么:

  1. 更多的工人。
  2. 工作人员的更多线程。
  3. 分配器上的更多线程。
  4. 启用/禁用 DTC
  5. 以上所有内容都在概念设置的基本证明中,其中包含仅带有 id 的消息。我们无法获得超过 100 条 msg 分布式公关。其次是工人。

这非常糟糕,因为我已经申请了更多的预算资金,如果我们不能很快获得更好的性能,我们必须放弃这个项目,我们将面临一些严重的麻烦:S。

问题:

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

我在 nservicebus 自己的网站上阅读了很多关于许可证的内容,但没有明确说明对开发人员许可证的限制。

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

[更新]

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

  1. 幸运的是,这表明我们没有完全错误地配置我们的 Distributor/Worker 设置。
  2. 不幸的是,这意味着我们仍然存在与 Distributor 的性能问题。

然后我想知道这是否真的是这样,并开始运行一些简单的线程,使用 Distributor 和 Workers 调整测试。经过一些尝试,我在示例中获得了高达 400-500 msg pr sec 的吞吐量。这是我发现的:

观察/解决方案:

  1. Distributor 需要更多的线程,而不仅仅是 1,但不能太多。现在我正在运行 2 个线程。我启动的工人。
  2. 如果我运行 20 或 100 个线程,Workers 通常会具有相同的性能。因此,我没有增加线程数量,而是增加了工作人员的数量,这起到了作用。
  3. 如果分发器或工作器上的线程数过多,它们似乎会遇到MSMQ 事务战斗,它们会相互阻塞,从而使系统突然阻塞。我可以使用 ScaleOut 示例和我自己的代码轻松重现阻塞,但是 TX 之战只是基于我阅读的文章的疯狂猜测,我不知道这就是正在发生的事情。

后续问题:

  1. 现在要做什么?我们应该用其他东西替换 MSMQ 还是这个问题是 NSB 内部的问题,可以在以后的版本中优化/修复?
  2. 这是 Distributor 的预期工作方式,这意味着我们唯一的解决方案是解雇更多的工人吗?
  3. 同一端点上的多个工作人员,但与分发器运行的机器不同,是否不会导致工作人员之间可能再次导致 MSMQ TX 战斗的竞争消费者情况?
  4. 示例和我们自己的代码之间有一个重要区别,我们禁用了 Raven 订阅存储,并且纯粹在 MSMQ 上运行,但据我所知,分销商不使用 Raven db 进行存储。我错了,这可能是一个获得一些表现的地方吗?

我现在正在做一些分布式测试,看看是否存在在同一台机器上启动多个工作人员的问题,但不是与分发服务器相同的机器。我希望这是可能的,而不必为每个工人设置单独的队列,因为我们已经为工人订购了额外的服务器并且没有更多的预算。

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

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

[更新 2]

如果我在 Visual Studio 外部使用 NServiceBus.Integration NServiceBus.Distributor/Worker 运行 ScaleOut 示例,并且只有 1 个工作人员,我可以获得 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());

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

亲切的问候。

4

0 回答 0