Azure Service Bus Configuration
MassTransit fully supports Azure Service Bus, including many of the advanced features and capabilities.
Minimal Example
To configure Azure Service Bus, use the connection string (from the Azure portal) to configure the host as shown below.
namespace ServiceBusConsoleListener;
using System.Threading.Tasks;
using MassTransit;
using Microsoft.Extensions.Hosting;
public class Program
{
public static async Task Main(string[] args)
{
await Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddMassTransit(x =>
{
x.UsingAzureServiceBus((context, cfg) =>
{
cfg.Host("connection-string");
});
});
})
.Build()
.RunAsync();
}
}
Broker Topology
With Azure Service Bus (ASB), which supports topics and queues, messages are sent or published to topics and ASB routes those messages through topics to the appropriate queues.
Configuration
Azure Service Bus queues includes an extensive set a properties that can be configured. All of these are optional, MassTransit uses sensible defaults, but the control is there when needed.
services.AddMassTransit(x =>
{
x.UsingAzureServiceBus((context, cfg) =>
{
cfg.Host("connection-string");
cfg.ReceiveEndpoint("input-queue", e =>
{
// all of these are optional!!
e.PrefetchCount = 100;
// number of messages to deliver concurrently
e.ConcurrentMessageLimit = 100;
// default, but shown for example
e.LockDuration = TimeSpan.FromMinutes(5);
// lock will be renewed up to 30 minutes
e.MaxAutoRenewDuration = TimeSpan.FromMinutes(30);
});
});
});
Host Settings
Property | Type | Description |
---|---|---|
TokenCredential | Use a specific token-based credential, such as a managed identity token, to access the namespace. You can use the DefaultAzureCredential to automatically apply any one of several credential types. | |
TransportType | Change the transport type from the default (AMQP) to use WebSockets |
For example, to configure the transport type to use AMQP over Web Sockets:
cfg.Host(connectionString, h =>
{
h.TransportType = ServiceBusTransportType.AmqpWebSockets;
});
Receive Settings
Property | Type | Description |
---|---|---|
PrefetchCount | int | The number of unacknowledged messages that can be processed concurrently (default based on CPU count) |
MaxConcurrentCalls | int | How many concurrent messages to dispatch (transport-throttled) |
LockDuration | TimeSpan | How long to hold message locks (max is 5 minutes) |
MaxAutoRenewDuration | TimeSpan | How long to renew message locks (maximum consumer duration) |
MaxDeliveryCount | int | How many times the transport will redeliver the message on negative acknowledgment. This is different from retry, this is the transport redelivering the message to a receive endpoint before moving it to the dead letter queue. |
RequiresSession | bool | If true, a message SessionId must be specified when sending messages to the queue (see sessions) |
Transport Options
All Azure Service Bus transport options can be configured using the .Host()
method. The most commonly used settings can be configured via transport options.
services.AddOptions<AzureServiceBusTransportOptions>()
.Configure(options =>
{
// configure options manually, but usually bind them to a configuration section
});
Property | Type | Description |
---|---|---|
ConnectionString | string | The connection string |
Additional Examples
Using Azure Managed Identity
The following example shows how to configure Azure Service Bus using an Azure Managed Identity:
services.AddMassTransit(x =>
{
x.UsingAzureServiceBus((context, cfg) =>
{
cfg.Host(new Uri("sb://your-service-bus-namespace.servicebus.windows.net"));
});
});
During local development, in the case of Visual Studio, you can configure the account to use under Options -> Azure Service Authentication. Note that your Azure Active Directory user needs explicit access to the resource and have the 'Azure Service Bus Data Owner' role assigned.
Using Service Bus Dead-letter Queues
MassTransit can be configured to use the built-in dead-letter queue instead moving messages to the _skipped or _error queues. Each can be configured independently.
To use the built-in dead-letter queue for all skipped and faulted messages on all receive endpoints:
services.AddMassTransit(x =>
{
x.AddConfigureEndpointsCallback((_, cfg) =>
{
if (cfg is IServiceBusReceiveEndpointConfigurator sb)
{
sb.ConfigureDeadLetterQueueDeadLetterTransport();
sb.ConfigureDeadLetterQueueErrorTransport();
}
});
x.UsingAzureServiceBus((context, cfg) =>
{
cfg.Host(new Uri("sb://your-service-bus-namespace.servicebus.windows.net"));
cfg.ConfigureEndpoints(context);
});
});
Using Service Bus Sessions
Receive Settings
Property | Type | Description |
---|---|---|
RequiresSession | bool | Set to true |
MaxConcurrentSessions | int | How many concurrent sessions to receive messages from (transport-throttled) |
MaxConcurrentCallsPerSession | int | How many concurrent messages to dispatch from each session (transport-throttled) |
SessionIdleTimeout | TimeSpan | How long to wait to receive a message before abandoning the session for another |
Batch Consumer
For batch-based in-order processing of sessions:
AddConsumer<MyBatchConsumer>(cfg =>
{
cfg.SetServiceBusSessionBatchOptions(o =>
o.SetMessageLimitPerSession(8)
.SetMaxConcurrentSessions(4)
.SetSessionIdleTimeout(TimeSpan.FromSeconds(30))
.SetTimeLimit(TimeSpan.FromSeconds(5))
);
});
Batches will be grouped by SessionId
Performance
We really recommend that you use the Premium subscription levels for production workloads. We have performed our own testing using MassTransit Benchmark on a P4 instance. It is also critical that your application is in the same DC as the ASB instance. From a home test using a 1Gb fiber connection we could not get over 600/second. When running in the same DC as the ASB we were able to acheive 6k/second. This test was done with one instance writing to ASB and another instance reading from ASB, as adding consumption over the same AMQP connection killed throughput.
Security Settings
Some security teams may initially balk at the necessity for your application to have the management role. Most teams value the developer productivity that comes with MassTransit managing the topics, queues, and subscriptions for them. In order to support this, MassTransit needs the Manage
permissions to support this development model.
When the Bus starts up, it will also confirm that the Topology is correct, and make any adjustments that are needed for ongoing work. To simply check the existence of queues and topics, Azure requires that the process have Manage
permissions. Some teams find this frustrating, and we encourge them to reach out to their Azure representative to request a finer grained access model.
When working with your Security and Compliance team, it can also be helpful to remind them that for most multi-service systems the MassTransit systems are running in an isolated Namespace. This namespace is usually only used by MassTransit services, and is not likely to interfere with anything other than this singular namespace. This creates a nicely defined "blast zone" that limits the scope of the impact.
You can read more about the Azure Service Bus security roles here: Mapping of Operations to Rights Needed