We currently have a machine running RabbitMQ 3.8.2 which we already use for some standard production work, however as we are now scaling out we need to be able handle more and more messages. Note: All work/testing below is on our test enviroment.
I am currently testing the publishing using NServiceBus (7.2.3) on .Net Core 3.1. This using messages which are roughly 70 to 80 bytes (however, lets keep it at 100), pushing to a Lazy queue.
When running the RabbitMQ Performance test using these parameters, i get a publish speed of about 25K to 30K messages per second.
When running on our end, publishing 100K messages takes on average 2 minutes (+/- 620 msg/sec)
As this process will be able to deploy a factor 20 more then 100K messages we need to up the speed.
Additional: Running the same test against an Azure Service Bus (standard) instance, gives a throughput of about 500 messages/sec
Now i am not expecting the same throughput as the PerfTest, but from 25K to just 600 is a big difference for me.
Is this expected? Can we increase this somehow?
Our NServiceBus setup is as follows.
Disabling the Heartbeat, Audit and ServiceControl does not matter in terms of performance.
.UseNServiceBus(hostBuilderContext =>
{
var nserviceBusConfig = hostBuilderContext.Configuration.GetSection("NServiceBus").Get<NServiceBusConfig>();
var endpointConfiguration = new EndpointConfiguration(Endpoints.Batch);
endpointConfiguration.UseSerialization<NewtonsoftSerializer>();
endpointConfiguration.EnableInstallers();
endpointConfiguration.LicensePath("/app/config/NServiceBusLicense.xml");
if (!string.IsNullOrEmpty(nserviceBusConfig.HeartbeatQueue))
{
endpointConfiguration.SendHeartbeatTo(
serviceControlQueue: nserviceBusConfig.HeartbeatQueue,
frequency: TimeSpan.FromSeconds(15),
timeToLive: TimeSpan.FromSeconds(30));
}
if (!string.IsNullOrEmpty(nserviceBusConfig.AuditQueue))
endpointConfiguration.AuditProcessedMessagesTo(nserviceBusConfig.AuditQueue);
if (!string.IsNullOrEmpty(nserviceBusConfig.MetricsQueue))
{
var metrics = endpointConfiguration.EnableMetrics();
metrics.SendMetricDataToServiceControl(
serviceControlMetricsAddress: nserviceBusConfig.MetricsQueue,
interval: TimeSpan.FromSeconds(2));
}
var recoverability = endpointConfiguration.Recoverability();
recoverability.Immediate(x => x.NumberOfRetries(5));
var transport = endpointConfiguration.UseTransport<RabbitMQTransport>();
transport.UseConventionalRoutingTopology();
transport.ConnectionString(HostHelpers.GetConnectionString(hostBuilderContext.Configuration, "Transport"));
SetRouting(transport);
return endpointConfiguration;
})
Publishing the messages to the queue is as follows:
var tasks = new ConcurrentBag<Task>();
Parallel.ForEach(lotCommands, new ParallelOptions { MaxDegreeOfParallelism = 20 }, command =>
{
tasks.Add(_messageSession.Send(command));
});
await Task.WhenAll(tasks);