The topology used by the transport is composed of several AWS components.
Amazon SQS exposes queue endpoints that are publicly available via HTTPS. Endpoints may access SQS queues whether they are deployed in AWS or not; as long as the endpoint can reach both SQS and S3 via HTTPS it can use the transport.
The transport initiates all network connections to SQS and S3; hence the endpoint itself does not need to be publicly accessible and can reside behind a firewall or proxy.
The transport uses SQS Standard Queues.
SQS queues support competing consumers. When an endpoint scales out to multiple instances, each instance consumes messages from the same input queue.
The transport is a multicast-enabled transport and provides built-in support for publish-subscribe messaging using Amazon Simple Notification Service (SNS). Publishing events to multiple endpoints is achieved by publishing a single message to an SNS topic to which multiple destination queues are subscribed.
The topology (topics and subscriptions) is created automatically by the subscribing endpoints. Topology deployment can be automated, or manually created, using the transport CLI tool. Refer to the transport operations section for more information.
Message inheritance support
By default topic names are generated using the message full type name and replacing characters that are not allowed in SNS. This has an impact on the way inheritance is supported by the transport. By default a subscriber will subscribe only to the most concrete type it knows about and a publisher will always publish the most concrete type it knows about. Inheritance at the subscriber level is not supported when using the automatically created topology.
In case a subscriber needs to subscribe to a message type that is not the most concrete type as seen by the publisher, a custom mapping is needed. For example, if a subscriber is subscribed to the
IOrderAccepted event defined in the
Contracts assembly it will create and subscribe to a topic named
namespace-IOrderAccepted. However, if in the same system the publisher publishes the
OrderAccepted message that implements
IOrderAccepted from the
Messages assembly it'll try to publish to the
namespace-OrderAccepted topic and the message won't be delivered to the desired destination.
For the described inheritance scenario to work properly, a custom mapping must be defined at the subscriber:
var transport = new SqsTransport(); transport.MapEvent<IOrderAccepted>("namespace-OrderAccepted"); endpointConfiguration.UseTransport(transport);
The above snippet instructs the subscriber's subscription manager to create and subscribe to a topic named
namespace-OrderAccepted when subscribing to the
More information about the custom mapping API can be found in the configuration options documentation.
Evolving an existing topology
Evolving an existing topology needs to be handled with care. The SQS Transport never deletes any resource so it might happen that messages are routed to undesirable destinations if or when message handlers are moved to a different endpoint, or completely removed.
For instance, in the following scenario:
- The system is composed by a publisher and a scaled-out subscribers (two instances, for the sake of the sample)
- An event needs to be removed as not anymore needed
- The message handler, for the removed event, needs to be removed with no subscribers downtime
The following steps needs to be put in place:
- Change the publisher first to stop publishing the event for which the handler needs to be removed
- Deploy the publisher changes
- Wait for in-flight messages to be consumed
- Change the subscriber by removing the not anymore needed handler
- Deploy subscribers instances one-by-one with no downtime
- Remove the SNS to SQS subscription for the specific event in AWS
- If not anymore needed, remove the SNS topic for the specific event
SQS supports a maximum message size of 256kb. The transport works around this size limit by using Amazon S3 to store message payloads for messages that are larger than 256kb in size. This allows the transport to send and receive messages of practically any size. Note that messages that fit in the 256kb size limit only use SQS; S3 does not come into play.
When a large message is sent, the transport uploads the message body to an S3 bucket and then sends an SQS message that contains a reference to the S3 object. On the receiving end the transport receives the message from SQS, identifies the reference to the S3 object, downloads it and processes the message as normal. When the message is to be deleted, the transport deletes the message from SQS, then deletes it from S3. To ensure that the message is deleted from S3, the transport applies a lifecycle policy to the S3 bucket that deletes any messages that are older than the configured time to live.