NServiceBus uses defaults that ensure good performance in common cases. While this is usually the preferred mode of operation there are situations where tuning might be desired.
Tuning concurrency
Examples where concurrency tuning might be relevant are:
- Non-thread-safe code that needs to run sequentially
- Databases that might deadlock when getting too many concurrent requests
Configuring concurrency limit
1
Limit maximum concurrency so that no more messages than the specified value are ever processed at the same time. If a maximum concurrency is not specified, the transport will choose an optimal value that is a balance between throughput and effective resource usage. The concurrency limit cannot be changed at run-time and can only be applied at endpoint instance creation and requires the instance to be restarted for concurrency changes to take effect.
Infrastructure monitoring should be set up for the environment that hosts the endpoint instance (as well as any remote resources, such as databases) to monitor CPU, RAM, network, and storage to validate if a change made to the concurrency is not negatively affecting the overall system.
Sequential processing
Set the concurrency limit value to 1
to process messages sequentially. Sequential processing is not a guarantee for ordered processing. For example, processing failures and recoverability will result in out-of-order processing.
Throttling
Limit the number of messages per second that the endpoint will process at any given time. This will help avoiding the endpoint from overloading sensitive resources that are using ressources like web-services, databases, other endpoints etc. Some examples would include
- An integration endpoint calling a web API, like
api.
, that have restrictions on the number or requests per unit of time allowed.github. com - A firewall that, for flood protection, limits the number of connections per second and IP address.
By default no throughput restrictions will be enforced.
Configuration
The default limits of an endpoint can be changed in both code and via app.config.
Via a IConfigurationProvider
public class ProvideConfiguration :
IProvideConfiguration<TransportConfig>
{
public TransportConfig GetConfiguration()
{
return new TransportConfig
{
MaximumConcurrencyLevel = 5,
MaximumMessageThroughputPerSecond = 10
};
}
}
Via app.config
By using raw xml.
MaximumConcurrencyLevel
and MaximumMessageThroughputPerSecond
. Set MaximumMessageThroughputPerSecond
only if the system needs to run slower.<configSections>
<section name="TransportConfig"
type="NServiceBus.Config.TransportConfig, NServiceBus.Core"/>
</configSections>
<TransportConfig MaximumConcurrencyLevel="5"
MaximumMessageThroughputPerSecond="10"/>
Run time settings
Concurrency and throughput throttling to be changed and read at run time using the code below.
Optimizing at run time
var transport = unicastBus.Transport;
transport.ChangeMaximumMessageThroughputPerSecond(10);
transport.ChangeMaximumConcurrencyLevel(5);
Reading current values at run time
var transport = unicastBus.Transport;
var messageThroughputPerSecond = transport.MaximumMessageThroughputPerSecond;
var maximumConcurrencyLevel = transport.MaximumConcurrencyLevel;