In a distributed message-based system, message correlation is very important. Since operations are potentially executing across hundreds of nodes, the ability to correlate different messages to build a path through the system is absolutely necessary for engineers to troubleshoot problems.
The headers on the message envelope provided by MassTransit already make it easy to specify correlation values. In fact, most are setup by default if not specified by the developer.
MassTransit provides the interface
CorrelatedBy<T>, which can be used to setup a default correlationId.
This is used by sagas as well, since all sagas have a unique
CorrelationId for each instance of the saga.
If a message implements
CorrelatedBy<Guid>, it will automatically be directed to the saga instance with the
matching identifier. If a new saga instance is created by the event, it will be assigned the
from the initiating message.
For message types that have a correlation identifier, but are not using the
it is possible to declare the identifier for the message type and MassTransit will use that identifier
by default for correlation.
MessageCorrelation.UseCorrelationId<YourMessageClass>(x => x.SomeGuidValue);
Most transactions in a system will end up being logged and wide scale correlation is likely.
Therefore, the use of consistent correlation identifiers is recommended. In fact, using a
type is highly recommended. MassTransit uses the NewId library
to generate identifiers that are unique and sequential that are represented as a
The identifiers are clustered-index friendly, being ordered in a way that SQL Server can efficiently
insert them into a database with the uniqueidentifier as the primary key. Just use
to generate an identifier -- it's fast, fun, and all your friends are doing it.
Correlation by convention
In addition to the explicit
CorrelateBy<T> interface, a convention-based correlation is supported.
If the message contract has a property named
EventId, the correlationId
header is automatically populated on Send or Publish. It can also be manually specified using the
Bear in mind that sagas default
CorrelateById() only support messages where the explicit
interface is implemented. However, the header is still useful if you do not use sagas, for example for
message flow analysis and debugging.
There are several other built-in message headers that can be used to correlate messages. However, it is also completely acceptable to add your own custom properties to the message contract for correlation.
In addition to the correlationId, the default headers include:
When using the
RequestClient, or the request/response message handling of MassTransit, each
request is assigned a unique
RequestId. When the message is received by a consumer, the response
message sent by the
Respond method (on the
ConsumeContext) is assigned the same
so that it can be correlated by the request client. This header should not typically be set by the
consumer, as it is handled automatically.
The conversation is created by the first message that is sent or published, in which no existing
context is available (such as when a message is sent or published by using
If an existing context is used to send or publish a message, the
ConversationId is copied to the
new message, ensuring that a set of messages within the same conversation have the same identifier.
When a message is created within the context of an existing message, such as in a consumer, a saga, etc.,
CorrelationId of the message (if available, otherwise the
MessageId may be used) is copied
InitiatorId header. This makes it possible to combine a chain of messages into a graph of
producers and consumers.
When a message is sent or published, this header is automatically generated for the message.