You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: nservicebus/best-practices.md
+11-15Lines changed: 11 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
---
2
2
title: Best practices
3
3
summary: An assortment of best practices presented as DO, DO NOT, and CONSIDER.
4
-
reviewed: 2024-01-05
4
+
reviewed: 2025-10-03
5
5
isLearningPath: true
6
6
---
7
7
@@ -13,9 +13,9 @@ This article presents recommendations to keep in mind when designing a system us
13
13
14
14
Multiple message handlers can be combined inside a single logical endpoint. However, these handlers all share a single message queue for different types of messages.
15
15
16
-
The endpoint is the fundamental unit of scale for an NServiceBus system. If one message handler has much higher throughput requirements, it can only be independently scaled if it exists in an endpoint by itself. In separate endpoints, only the message handler that has the unique scalability requirements has to be scaled out.
16
+
The endpoint is the fundamental unit of scale for an NServiceBus system. If one message handler has much higher throughput requirements, it can only be independently scaled if it exists in an endpoint by itself. With separate endpoints, only the message handler that has the unique scalability requirements has to be scaled out.
17
17
18
-
The endpoint is also the fundamental unit of deployment for an NServcieBus system. That means that the entire endpoint must be redeployed if a fix is required for one message handler. The fewer message handlers in each endpoint, the less likely any individual deployment is to cause a problem in the system since the whole system does not have to be redeployed on every change.
18
+
The endpoint is also the fundamental unit of deployment for an NServiceBus system. That means that the entire endpoint must be redeployed if a fix is required for one message handler. The fewer message handlers in each endpoint, the less likely any individual deployment is to cause a problem in the system since the whole system does not have to be redeployed on every change.
19
19
20
20
### :heavy_check_mark:**CONSIDER grouping message handlers by SLA**
21
21
@@ -43,11 +43,11 @@ Meanwhile, a custom abstraction makes the NServiceBus documentation less effecti
43
43
44
44
It is best to embrace the asynchronous nature of NServiceBus messages and not use an asynchronous message (or a pair of messages in a request/reply scenario) for synchronous communication, especially when the scenario expects an answer to be available _right now_. This is especially important with queries: [messaging should not be used for queries](https://web.archive.org/web/20211205190919/http://andreasohlund.net/2010/04/22/messaging-shouldnt-be-used-for-queries/).
45
45
46
-
When a previously-defined user interface demands an immediate response, such as inserting a new item into a grid and then immediately refreshing the grid to include the new item, the [client-side callbacks package](/nservicebus/messaging/callbacks.md) can be used, but this should be considered a crutch until a more [task- or command-focused UI](https://cqrs.wordpress.com/documents/task-based-ui/) can replace it.
46
+
When a previouslydefined user interface demands an immediate response, such as inserting a new item into a grid and then immediately refreshing the grid to include the new item, the [client-side callbacks package](/nservicebus/messaging/callbacks.md) can be used, but this should be considered a temporary workaround until a more [task- or command-focused UI](https://cqrs.wordpress.com/documents/task-based-ui/) can replace it.
47
47
48
48
### :x:**DO NOT create a messaging endpoint for every single web request**
49
49
50
-
NServiceBus does a lot of work when it first starts up, scanning through assemblies to find the types of messages and message handlers, establishing communication with the messaging infrastructure, and ensuring that everything is optimized to run quickly for the duration of the endpoint's life. Do not repeat all this work on every web request just to send a single message and then shut down.
50
+
NServiceBus does a lot of work when it first starts up, including scanning through assemblies to find the types of messages and message handlers, establishing communication with the messaging infrastructure, and ensuring that everything is optimized to run quickly for the duration of the endpoint's life. Do not repeat all this work on every web request just to send a single message and then shut down.
51
51
52
52
An NServiceBus endpoint is designed to be a long-lived object that persists throughout the application process. Once the `IMessageSession` is created, use dependency injection to inject it into controllers or wherever else it is needed. If necessary, assign the `IMessageSession` to a global variable.
53
53
@@ -63,7 +63,7 @@ Asynchronous messaging (e.g., NServiceBus) is **not** a good solution for data d
63
63
64
64
Message handlers should be simple and focused on only the business code needed to handle the message. Infrastructure code for logging, exception management, timing, auditing, authorization, unit of work, message signing/encryption, etc, should not be included in a message handler.
65
65
66
-
Instead, implement this functionality separately in a [message pipeline behavior](/nservicebus/pipeline/manipulate-with-behaviors.md), which enables inserting additional functionality into the NServiceBus message processing pipeline, similar to an ASP.NET ActionFilter.
66
+
Instead, implement this functionality separately in a [message pipeline behavior](/nservicebus/pipeline/manipulate-with-behaviors.md), which enables inserting additional functionality into the NServiceBus message processing pipeline.
67
67
68
68
For a high-level overview of infrastructure concerns and behaviors, see the blog post [Infrastructure soup](https://particular.net/blog/infrastructure-soup).
69
69
@@ -98,21 +98,17 @@ Message queues are long-lasting and durable. Occasionally connected clients, suc
98
98
99
99
For occasionally connected clients, consider another communication medium, such as in the [Near real-time transient clients sample](/samples/near-realtime-clients/), which communicates with clients using [SignalR](https://dotnet.microsoft.com/apps/aspnet/signalr).
100
100
101
-
### :heavy_check_mark:**CONSIDER [identifying message types using conventions](/nservicebus/messaging/unobtrusive-mode.md) to make upgrading to new versions of NServiceBus easier**
101
+
### :heavy_check_mark:**Consider using shared message assemblies that reference [NServiceBus.MessageInterfaces](https://www.nuget.org/packages/NServiceBus.MessageInterfaces) to make upgrading to new versions of NServiceBus easier**
102
102
103
-
By default, NServiceBus will identify classes implementing `ICommand` as commands, `IEvent` as events, and `IMessage` as other types of messages, such as replies. This is quick and easy but also causes message projects to depend on the NServiceBus NuGet package.
103
+
In a complex system, it's useful to be able to upgrade one endpoint at a time. Message assemblies are shared between multiple endpoints. If these assemblies reference the NServiceBus NuGet package directly, they can cause challenges during upgrades when one endpoint using a message assembly has upgraded to the next major version but the other has not.
104
104
105
-
In a complex system, it's useful to be able to upgrade one endpoint at a time. Message assemblies are shared between multiple endpoints, which can cause challenges during upgrades when one endpoint using a message assembly has upgraded to the next major version but the other has not.
106
-
107
-
These versioning problems can be addressed using [unobtrusive-mode messages](/nservicebus/messaging/unobtrusive-mode.md) by defining [message conventions](/nservicebus/messaging/conventions.md) independent of the `ICommand`/`IEvent`/`IMessage` interfaces.
108
-
109
-
These conventions can even be [encapsulated in a class](/nservicebus/messaging/conventions.md#encapsulated-conventions), and many can be used within one endpoint so that messages from multiple teams who have made different choices on message conventions can be used together.
105
+
To solve this, message assemblies should instead reference the [`NServiceBus.MessageInterfaces` package](/samples/message-assembly-sharing/) which has no dependency on the NServiceBus package.
110
106
111
107
## System monitoring
112
108
113
-
### :heavy_check_mark:**DO install the [Heartbeats plugin](/monitoring/heartbeats/) in all endpoints to monitor for endpoint health**
109
+
### :heavy_check_mark:**DO install the [Heartbeat plugin](/monitoring/heartbeats/) in all endpoints to monitor for endpoint health**
114
110
115
-
The Heartbeats plugin sends a message to [ServiceControl](/servicecontrol/) at regular intervals to demonstrate that the process is not only executing (which would be provided by any suite of system monitoring tools) but is also capable of interacting with the message transport.
111
+
The Heartbeat plugin sends a message to [ServiceControl](/servicecontrol/) at regular intervals to demonstrate that the process is not only executing (which would be provided by any suite of system monitoring tools) but is also capable of interacting with the message transport.
116
112
117
113
If ServiceControl stops receiving heartbeat messages from an endpoint, that endpoint will be shown as [inactive in ServicePulse](/monitoring/heartbeats/in-servicepulse.md). In addition, ServiceControl will publish a [`HeartbeatStopped` event](/monitoring/heartbeats/notification-events.md) so that operations staff can be notified and respond.
0 commit comments