Azure Service Bus alternative to transactional outbox pattern - azure

Let's say I have this generic saga scenario (given three distinct microservices A, B, and C, communicating with messaging):
1. Service A
a. Performs operation A successfully
b. Communicates update with message A
2. Service B (after receiving message A)
a. Performs operation B successfully
b. Communicates update with message B
3. Service C (after receiving message B)
a. Fails to perform operation B
b. Communicates failure
4. Service A and B performs compensating actions
It is my understanding that while the entire workflow should be eventually consistent, you want to ensure that the local operations (the a and b) are transactionally consistent to avoid losing messages (or if reverse, avoid sending messages but fail to persist operation changes).
This is the problem that the transactional outbox pattern aims to solve, if I'm not mistaken.
In the context of .NET on Azure, using
EF Core
Azure Service Bus
Is there a way to get the same level of transactional security without saving the message to the database (i.e. not using a transactional outbox)?
I've seen a lot of System.Transactions mentions, but it's either being used for multiple database operations or multiple service bus operations, not database and service bus operations together.
Could something like this achieve the desired transactional consistency?
using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
// _dbContext.Database.EnlistTransaction(ts); <-- ?
_dbContext.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
_dbContext.SaveChanges();
await _serviceBusSender.SendMessageAsync(new ServiceBusMessage());
ts.Complete();
}

No, you can't achieve that as different resources cannot participate in a single transaction as that would become a distributed transaction, which is undesired in a cloud environment.
To ensure your data and messaging operations share the same transaction, you'd be looking into some sort of persistence such as outbox.
Frameworks such as NServiceBus provide support for outbox with Azure Service Bus as a transport and SQL Server or document database as a data store.

Related

Azure Service Bus Queues vs. Topics (Pub/Sub)

Need a bit of architectural guidance. I have a set of stateless services that do various functions. My architecture allows for multiple copies of each service to run at the same time (as they are stateless), allowing me to:
scale up as needed for handling larger workloads
have fault-tolerance (if one instance of a service fails, no problem as there will be others to take on that work).
However, I don't want duplication of work.
If Service A, Instance 1 has already taken Job ABC, I don't want Service A, Instance 2, to take on that same job. So, I could avoid this problem by using Azure Service Bus Queues. Only a single worker would get a particular item from the queue and would only be reassigned to another worker, if the worker didn't mark it as complete in a set time.
So what's an appropriate use-case for Topics (Pub/Sub)? It seems like if I ever have multiple copies of the same service, I must rely on Queues. Is that right?
Asked another way, is there a way to use Topics in Azure Service Bus or similar products/services but avoid duplication of work? Also, if there is a way to lock a message (for a short period of time) when using Topics, is it possible to lock that message to just one instance of Service A (so no other instances of Service A will have access to it) but the message will be broadcast to Service B, Service, C, etc.?
is there a way to use Topics in Azure Service Bus or similar
products/services but avoid duplication of work?
Yes, there is. Basically with that you would need to use each subscription as a queue. What you will need to do is define proper filters so that one kind of message is sent to a single subscription (that way it acts as a queue) and have multiple listeners (service instances in your case) listen to a specific subscription only.
Also, if there is a way to lock a message (for a short period of time)
when using Topics, is it possible to lock that message to just one
instance of Service A (so no other instances of Service A will have
access to it) but the message will be broadcast to Service B, Service,
C, etc.?
It is certainly possible to lock a message. For that you will need to fetch messages in Peek-Lock mode. However if multiple subscribers (services) are involved, then only one subscriber will be able to lock the message and access it. For other subscribers, the message will be invisible. You can't have a scenario where one service acquires the lock and other services still receive the message.
Azure function triggers would provide all what you are looking for out of the box.
If you are not leveraging any advanced queuing features of service bus then I would recommend you look at storage queues to save some money.
If you need service bus then you can use service bus triggers.
Hope that helps.

Is it a good pattern to use Azure service bus as backup messaging service?

We are considering of a design pattern where
Web service tries to insert data into database
If that call fails and db is not available
then we pass that data into azure service bus
Once the db is back up, some other service will read data from service bus and insert into database.
I personally have not seen this pattern however is there any issue with this design ?
The way queuing system are usually used is slightly different from what you're asking.
Queues allow reliable command execution if the destination resource is not available (database) and balance the load on the resource rather than overwhelming it.
The steps would be:
Web service sends a Service Bus message with the data that needs to be inserted into the database.
A backend service is peeking the messages and tries to insert into the database.
If the operation is failing or the database is not available, the message is retried.

Azure Service Bus Topic Subscriber receiving messages not in order

I am using azure service bus topic and I have enable session for it's subscription.
With in the my logic app i am inserting data using sql transaction which are coming from topic
I am using topic Subscription(peek-lock) and
in subscriber level concurrency is set to default as follows
According to my Understanding, my logic app(subscriber) should read ALL the messages and have to processed in FIFO
my logic app is like
which means it should insert data to the table in ordered manner
however when i checked in the trigger log it shows correct order but in database level you can see the order is not happening
Message ordering is a delicate business. You can have either message ordering or concurrent processing, but not both. The moment you make message ordering a must, you lose the ability to have concurrent processing. This is correct for both, Azure Service Bus Sessions and Logic Apps concurrency control. You could process multiple sessions, but each session would be still restricted to a single processor. Here's a post about it.

Service Fabric Stateful services with single DB Persistance service

I'm about to start a project that requires very fast response times and high availability, i have done a few service fabric projects before so i'm feeling pretty confident about that.
I'm currently leaning towards a specific design, based on stateful content services as main datasource with a single data persistance service saving to a database of some sort.
Read operations are done by web-api
Write operations are done by Azure service bus communication with Rebus as handler.
Content services
The content services are stateful services which on commit sends a message to the persistance service with the object saved in the reliable dictionary, serialized as json.
The content services them selves will be responsible for json deserialization in the event that they need to restore the data.
Restore scenarios could be when the entire dictionary for some reason is lost or when a reset message is put on the bus.
Persistance service
Recieves a message from the bus and stores the included entity, to a data store (Not yet decided, maybe table storage).
Serves an entire repository of data when a service need to reload data.
Only concerns itself with storing and retrieving data, no integrity checks
I'm really unsure about whether this is a feasible way of designing a system, that also has a high amount of user data.
what are your thoughts on this design?
I ended up pursuing this solution and it works quite well and performs very well but it needs extensive testing in order to make sure that everything works as expected.

Ways to make a broker at Azure for anonymous HTTP API messages?

We need API at Azure that would store messages sent to it (broker) via HTTP in case my system (Cloud Service) unavailable or DB is busy. It's not easy to change what exact message will be sent. What ways to make such a broker at Azure?
Service Bus Queue looks interesting but it needs Shared Access Signatures as far as I understand.
Another WebRole should be a solution but it needs time to implement.
Virtual Machine with some tool (MSMQ?) seems a way but it requires maintenance.
What do you think?
Your scenario is a prime candidate for applying a Queue-Centric Work Pattern.
From http://www.asp.net/aspnet/overview/developing-apps-with-windows-azure/building-real-world-cloud-apps-with-windows-azure/queue-centric-work-pattern:
If either your Worker(s) or Database become unavailable, messages are still placed in durable storage and consumed later.
The Task Queue can take the form of an Azure Storage Queue or a Service Bus Queue. In every great design, the least complex component that does the job wins. In this case that would be Azure Storage Queues, durable, reliable, very few moving parts. Unless you absolutely need precision FIFO ordering, in which case you go with Service Bus.
From https://msdn.microsoft.com/en-us/library/dn568101.aspx:
This solution offers the following benefits:
It enables an inherently load-leveled system that can handle wide variations in the volume of requests sent by application instances. The queue acts as a buffer between the application instances and the consumer service instances, which can help to minimize the impact on availability and responsiveness for both the application and the service instances (as described by the Queue-based Load Leveling pattern). Handling a message that requires some long-running processing to be performed does not prevent other messages from being handled concurrently by other instances of the consumer service.
It improves reliability. If a producer communicates directly with a consumer instead of using this pattern, but does not monitor the consumer, there is a high probability that messages could be lost or fail to be processed if the consumer fails. In this pattern messages are not sent to a specific service instance, a failed service instance will not block a producer, and messages can be processed by any working service instance.
It does not require complex coordination between the consumers, or between the producer and the consumer instances. The message queue ensures that each message is delivered at least once.
It is scalable. The system can dynamically increase or decrease the number of instances of the consumer service as the volume of messages fluctuates.
It can improve resiliency if the message queue provides transactional read operations. If a consumer service instance reads and processes the message as part of a transactional operation, and if this consumer service instance subsequently fails, this pattern can ensure that the message will be returned to the queue to be picked up and handled by another instance of the consumer service.
Given you can't change the client, I would proxy the call. Recreate the API using the API Management Service in Azure, and change the web url to point to the API Management Service proxy.
The proxy can then easily delegate to a function application like Aravind mentioned in the comments to your question by using the API Management Service policies.

Resources