I am using Azure Service Bus to implement message communication between separate bounded contexts. I am curious about what techniques people use to ensure that domain events raised in one bc are guaranteed to be received by another consuming bc.
For example, say the "orders" bc raises an "orderPlaced" event, how can I ensure that this event is received by a "shipping" bc. I understand that 2 phase commit is not advisable in cloud, so what is the alternative? How do I mitigate against the order being placed, but the message failing to be sent to the service bus in the event of a network failure?
Thoughts would be welcomed. Thanks.
If you send a BrokeredMessage to a Service Bus Queue and receive an acknowledgement, the message has been successfully stored in the queue. You don't have to worry about the message dying in transit due to a network error after you've been told it is persisted.
What you can worry about is a Service Bus Queue falling offline for a period of time and being unavailable. During an outage, your orderPlaced message wouldn't be able to get into the queue in the first place, and your shipping logic wouldn't be able to receive orders that are already persisted in your queue.
Note that Service Bus Queue outages are transient and the Queue recovers and returns to normal service. At that time, your shipping app could drain the queue of existing messages, and your ordering app could once again insert orderPlaced messages. I don't actually recall the last time I've seen one of my Service Bus Queues go down - it's a rare event.
If you are super-concerned about never ever ever EVER dropping a message, look at paired namespaces. Basically, this allows for failover to standby queues so that you can insert messages while your primary is down. Automatic detection checks to see when your primary queue comes back online. And a siphon process sucks messages that were inserted into the failover queue during the outage back into the primary once the primary comes back online.
Edit: When sending, there is still the chance that even though you had a valid Service Bus Queue connection in your QueueClient or MessagingFactory, the underlying Service Bus Queue just went down like a glass-jawed prizefighter. The vast majority of the time, these errors are transient. To handle them, set the RetryPolicy property of your MessagingFactory or QueueClient. Off the top of my head, I think that the only policy currently available is the RetryExponential policy. This will perform a back-off that will retry sending the message until the specified number of attempts are exhausted. This is the easy-peasy way to handle transient errors that pop up in your Service Bus Queue connection.
Related
I have a client that pushes messages into a Service Bus. I
have an Azure Function on the other side that is bound to the Service Bus so that it is automatically called when a message is posted in the Service Bus.
(Client) ---Message---> (Service Bus) ---Message---> (Azure Function)
The Service Bus guarantees that the first message in the queue will be the first to get out (FIFO).
Now, I assume that, under a certain load, several Azure Functions will be started to process the messages from the Service Bus.
Let's say one of these Azure Functions crashes (for whatever reasons) and is unable to process a message.
Question
Does the Service Bus put back the unprocessed message back in the first place and does that mean that, technically, even if this message was the first in the queue, it can indeed be processed after a more recent message?
You need to properly set the SessionID to guarantee order. For session-aware entities, this application-defined value specifies the session affiliation of the message. Messages with the same session identifier are subject to summary locking and enable exact in-order processing and demultiplexing. For session-unaware entities, this value is ignored. See Message Sessions.
https://learn.microsoft.com/en-us/azure/service-bus-messaging/message-sessions
I've relatively new to Azure Service Bus Queues and am building a project that needs to process messages in a queue in the order in which they arrive (FIFO).
Using Microsoft's documentation, I was able to figure that part out. From what I understand I need to turn sessions on for the queue?
What I'm struggling with is determining what would be the best approach / service stack to perform the following set of ordered tasks against the queue.
First let's assume that we have a FIFO-based Service Bus Queue in place that has n number of messages. How might I:
Pick up the first message from the queue.
Process the message using an Azure Function.
Send a payload to IoT Hub that will deliver to an external device (C2D).
This is the part that I can't figure out...Wait for either a Completed indicator to return from IoT Hub or wait until the TTL expires for the outgoing IoT Hub Message.
Now complete the item in the queue.
Start back at 1.
I would imagine that perhaps a Logic App might help me achieve what I'm attempting to do. Everything seems straight forward up until #4. I can't figure out how to have the logic app 1. Wait until IoT Hub acknowledges that the Cloud-to-Device message was sent or expired and 2. Don't process the next message in the queue until the IoT Hub acknowledgment has been received and I've marked the current queue message as complete.
Please be advised: The reason why I'm so specific about this is that the devices receiving the outgoing IoT Hub C2D messages care about order. If they receive messages out of order, it throws the process off.
Any suggestions is greatly appreciated.
Azure Service bus Queues with Session can be used for achieving ordered processing of the message.
From the question, I can understand that the message from the Service Bus Queue should be removed only after the acknowledgement is received from IOT Hub.
I can sense a problem that may happen with this flow.
First of all, you need to understand about lock duration property in Service Bus Queue. Based on the value set to this property, the messages will be locked for x minutes or seconds. Whenever a message is received from a Queue, a lock will be applied for the message. So that the message will not be available for any other receivers for x minutes or seconds. Complete operation should happen before the lock gets expired. Once the lock is expired, the message will be available for other receivers to process. In your case, there is a chance for the same Azure Function to receive the message once again (resulting in duplication)
The maximum value that can be set for the lock duration property is 5 minutes.
So, if you are sure that the IOT Hub responds with in 5 minutes, you can proceed with this implementation. Still, there will be no option to let the Function know when to process the next message.
Currently, I have a problem handling data which I have sent from application to azure queue. The data I sent required to be sent FIFO but the Azure Queue cannot guarantee to be in order. Whereas Azure Service Bus Queue was guaranteed to be FIFO.
I am not sure is Azure Service Bus Queue has any differences with the Azure Queue.
As a solution architect/developer, you should consider using Storage queues when:
Your application must store over 80 GB of messages in a queue, where the messages have a lifetime shorter than 7 days.
Your application wants to track progress for processing a message inside of the queue. This is useful if the worker processing a message crashes. A subsequent worker can then use that information to continue from where the prior worker left off.
You require server side logs of all of the transactions executed against your queues.
As a solution architect/developer, you should consider using Service Bus queues when:
Your solution must be able to receive messages without having to poll the queue. With Service Bus, this can be achieved through the use of the long-polling receive operation using the TCP-based protocols that Service Bus supports.
Your solution requires the queue to provide a guaranteed first-in-first-out (FIFO) ordered delivery.
You want a symmetric experience in Azure and on Windows Server (private cloud). For more information, see Service Bus for Windows Server.
Your solution must be able to support automatic duplicate detection.
You want your application to process messages as parallel long-running streams (messages are associated with a stream using the SessionId property on the message). In this model, each node in the consuming application competes for streams, as opposed to messages. When a stream is given to a consuming node, the node can examine the state of the application stream state using transactions.
Your solution requires transactional behavior and atomicity when sending or receiving multiple messages from a queue.
The time-to-live (TTL) characteristic of the application-specific workload can exceed the 7-day period.
Your application handles messages that can exceed 64 KB but will not likely approach the 256 KB limit.
You deal with a requirement to provide a role-based access model to the queues, and different rights/permissions for senders and receivers.
Your queue size will not grow larger than 80 GB.
You want to use the AMQP 1.0 standards-based messaging protocol. For more information about AMQP, see Service Bus AMQP Overview.
You can envision an eventual migration from queue-based point-to-point communication to a message exchange pattern that enables seamless integration of additional receivers (subscribers), each of which receives independent copies of either some or all messages sent to the queue. The latter refers to the publish/subscribe capability natively provided by Service Bus.
Your messaging solution must be able to support the "At-Most-Once" delivery guarantee without the need for you to build the additional infrastructure components.
You would like to be able to publish and consume batches of messages.
https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-azure-and-service-bus-queues-compared-contrasted
Messages in Storage queues are typically first-in-first-out, but sometimes they can be out of order; for example, when a message's visibility timeout duration expires (for example, as a result of a client application crashing during processing). When the visibility timeout expires, the message becomes visible again on the queue for another worker to dequeue it. At that point, the newly visible message might be placed in the queue (to be dequeued again) after a message that was originally enqueued after it.
You will find this article helpful in making the decision for your case: Storage Queues and Service Bus Queue comparison. It compares some of the fundamental queuing capabilities provided by Storage queues and Service Bus queues.
Also read Get started with Service Bus Queues.
My scenario: I have an Azure Storage Queue where messages can come in at any time. If I have 10 items in that queue, it's imperative that they be processed in order. I'm using c# and the windows azure storage SDK.
If the first item fails after, say, 2 seconds it remains invisible on the queue for another 28 seconds (30 second invisibility by default).
Now, my worker will just continue to check a queue for messages and process them as and when. If a queue message fails, it remains invisible and so the next queue item will be processed before the first message is retried.
This seems like really basic functionality for anyone needing a queue where the items are processed in order.
No, I can't set the timeout to a smaller amount because tasks can take varying lengths of time.
George, if you are looking for a messaging queue solution that processes items in order, you should consider using Azure Service Bus Queues:
As a solution architect/developer, you should consider using Service Bus queues when:
Your solution must be able to receive messages without having to poll the queue. With Service Bus, this can be achieved through the use of the long-polling receive operation using the TCP-based protocols that Service Bus supports.
Your solution requires the queue to provide a guaranteed first-in-first-out (FIFO) ordered delivery.
You want a symmetric experience in Azure and on Windows Server (private cloud).
For more information, see Service Bus for Windows Server.
Your solution must be able to support automatic duplicate detection.
There is a good article comparing both Storage Queues and Service Bus: https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-azure-and-service-bus-queues-compared-contrasted , you may find the latter better suitable for your case.
You can subscribe to asynchronous updates from Azure topics and queues by using SubscriptionClient/QueueClient's .OnMessage call which will presumably create a separate thread polling the topic/queue with default settings and calling a defined callback if it receives anything.
Azure website says that receiving a message is a billable action, which is understandable. However, it isn't clear enough if each those poll requests are considered billable even when they do not return anything, i.e. the queue in question has no pending messages.
Based on the Azure Service Bus Pricing FAQ - the answer to your question is yes
In general, management operations and “control messages,” such as
completes and deferrals, are not counted as billable messages. There
are two exceptions:
Null messages delivered by the Service Bus in
response to requests against an empty queue, subscription, or message
buffer, are also billable. Thus, applications that poll against
Service Bus entities will effectively be charged one message per poll.
Setting and getting state on a MessageSession will also result in
billable messages, using the same message size-based calculation
described above.
Given the price is $0.01 per 10,000 messages, I don't think you should worry too much about that.