nservicebussubscribernservicebus-distributornservicebus3

NServiceBus - scaling out subscriber duplicates events across master and worker


My core question is how to scale out a subscriber in NServiceBus. Please let me know what I'm doing wrong or what I've missed. I'll gladly answer any questions about my setup.

Scenario:

I'm seeing what I hope is incorrect behavior in my attempts to scale out a subscriber. I've got the master on machine 01, and the worker on machine 02. I uninstalled both services and reinstalled with "NServiceBus.Production NServiceBus.Master" as the command line for the master and the same but with NServiceBus.Worker for the worker. Both services are running fine with two threads available. I ran the first part of my scenario with the services turned off and the queue counts are as in the first list below. Notice the 816 messages in both the Master and the Worker? I thought that installing with the Production command line would cause the two services to share the same subscription information and only the master would receive the subscribed-to events, but I was mistaken. These are pure dupes in both the worker and the master.

The second set of queue counts is the result of launching both services and letting them finish processing. Notice how the worker service on 02 processed his original 816 plus whatever the distributor gave him?

The gateway, retries, and timeouts queues for the master and the retries and timeouts queues for the worker aren't listed here because their values were 0 for both the queues and the journal, before and after running the services

// Services OFF ****************************************

FormatName:DIRECT=OS:vm-01\private$\creditalertnotificationprocessor.distributor.control

Queue Messages: 0

Journal Messages: 0

FormatName:DIRECT=OS:vm-01\private$\creditalertnotificationprocessor.worker

Queue Messages: 0

Journal Messages: 0

FormatName:DIRECT=OS:vm-01\private$\creditalertnotificationprocessor.distributor.storage

Queue Messages: 5

Journal Messages: 0

FormatName:DIRECT=OS:vm-01\private$\creditalertnotificationprocessor

Queue Messages: 816

Journal Messages: 0

FormatName:DIRECT=OS:vm-02\private$\creditalertnotificationprocessor

Queue Messages: 816

Journal Messages: 0

// Services ON (and finished) ********************************

FormatName:DIRECT=OS:vm-01\private$\creditalertnotificationprocessor.distributor.control

Queue Messages: 0

Journal Messages: 1634

FormatName:DIRECT=OS:vm-01\private$\creditalertnotificationprocessor.worker

Queue Messages: 0

Journal Messages: 483

FormatName:DIRECT=OS:vm-01\private$\creditalertnotificationprocessor.distributor.storage

Queue Messages: 824

Journal Messages: 817

FormatName:DIRECT=OS:vm-01\private$\creditalertnotificationprocessor

Queue Messages: 0

Journal Messages: 816

FormatName:DIRECT=OS:vm-02\private$\creditalertnotificationprocessor

Queue Messages: 0

Journal Messages: 1149

Worker config file...

    <?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
    <section name="MessageForwardingInCaseOfFaultConfig" type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core" />
    <section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
    <section name="MasterNodeConfig" type="NServiceBus.Config.MasterNodeConfig, NServiceBus.Core" />
  </configSections>

  <MasterNodeConfig Node="vm-01"/>

  <UnicastBusConfig>
    <MessageEndpointMappings>
      <add Messages="Sample.Common.Messages.Commands.LogMessage, Sample.BusFramework.Common" Endpoint="Sample.BusFramework.LogMessageProcessor@vm-01" />
      <add Messages="Sample.Credit" Endpoint="Sample.Credit.AlertBackfillProcessor" />
    </MessageEndpointMappings>
  </UnicastBusConfig>
  <MessageForwardingInCaseOfFaultConfig ErrorQueue="error" />
  <MsmqTransportConfig NumberOfWorkerThreads="2" MaxRetries="1" />

  <connectionStrings>
    <add name="ApplicationLog" connectionString="" providerName="" />
    <add name="ProductFulfillment" connectionString="" providerName="" />
  </connectionStrings>

  <appSettings>
    <add key="BusLoggingThreshold" value="DEBUG"/>
  </appSettings>

</configuration>

Solution

  • You don't need to subscribe via the MessageEndpointMappings in the config. The Master will subscribe and delegate processing to this node. You are seeing duplicates because the Worker is subscribed on its own.