Skip to main content

Active/Active Mechanism over Azure Service Bus

In one of my latest post I talk about Azure Service Bus and Active/Passive mechanism that works great when you need  fail-over mechanism.
Using this mechanism the system can use a secondary channel to send messages in case of the connectivity or reliability problems with the first resources (in our case with our Active namespace). The Passive resource it is recommended to be placed in another region (data-center). In this way there is better protection in a case of a fail-over.

The downside of Active/Passive Mechanism is the risk of losing messages that were send with success on the channel. There is a risk of loosing messages when the Active resource goes down. If the system that sends messages over the wire is not capable to send again the lost messages than you could have an issues. This use case it is important only for use cases when it is not acceptable to lose messages.
For example in the above example (from the Active/Passive post, when backed send messages to the car, we want to be sure that Open Doors command will reach the car. We don't want to have a customer waiting 1h until the doors would open.

In the above example if the Active channel goes down (queue), all messages that were to Active Service Bus Queue and were not consumed by the consumer are not available anymore.
If is important to be able to still access them, even when the Active channel is down, then we will need to use Active/Active Mechanism.
Be aware, from all points of view, this is more expensive then Active/Passive Mechanism and you should use it only when you really need it.

The main difference between Active/Passive and Active/Active Mechanism is the way how messages are send and consumed. When we are using Active/Passive Mechanism a message is send to the Active resource all the time. Except when the Active is down and cannot be reached by producer. In this case the message is send the Passive resource. The consumer is usually listening both resources (Active/Passive), but the Active resource is usually checked more often.
In contrast, in Active/Active Mechanism, the producer will send each message to both resources. In this way, in the case of a fail-over of one resource, the other one will still have the message. This comes with an overhead on the consumer side.

Because the same message is send to both resources, the consumer needs to track messages.It needs to be able to skip messages that were already processed.

Tracking messages action can be done pretty simple using a caching mechanism.
A possible solution for this problem could be based on Redis Cache. As you already know, Redis Cache is not only extremely fast and reliable but also allow us to set an TTL (an expiration time) for each item that is added to the cache. In this way we can specify how long a key will will be stored and exist in the cache.
Using this functionality we could have the fallowing mechanism:
  1. [Producer] Send a message to both Active resources (to both Service Bus Queues) and setting the same unique message ID to both messages (SyncID - Guid)
  2. [Consumer] Receive message from one of the Active Resource
  3. [Consumer] Check if the message SyncID was already added to Redis Cache (consumed). If yes then skip next steps
  4. [Consumer] Add the message SyncID to Redis Cache
  5. [Consumer] Execute custom action

We could use the expiration flag to be sure that the cache stores only relevant information. Beside this, we could use Sets to store the Message SyncID. A Redis Set allow us to store around 4 billions items.

Of course for message tracking we can use other mechanism and even store different status. Beside Redis Cache we could use Azure Table a normal SQL database. Don't try to use in-memory storage when you have multiple instances that are connection to the same Active/Active resources. Why? Because you will need to find a way to sync the in-memory storage between different instances.

In this post we discover what are the advantages of Active/Active Mechanism and when we should use it. It is true that it is more reliable, but the resources that are required for such a system are higher (and is more expensive).


Popular posts from this blog

ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded

Today blog post will be started with the following error when running DB tests on the CI machine:
threw exception: System.InvalidOperationException: The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See for more information. at System.Data.Entity.Infrastructure.DependencyResolution.ProviderServicesFactory.GetInstance(String providerTypeName, String providerInvariantName) This error happened only on the Continuous Integration machine. On the devs machines, everything has fine. The classic problem – on my machine it’s working. The CI has the following configuration:

TeamCity.NET 4.51EF 6.0.2VS2013
It seems that there …

Entity Framework (EF) TransactionScope vs Database.BeginTransaction

In today blog post we will talk a little about a new feature that is available on EF6+ related to Transactions.
Until now, when we had to use transaction we used ‘TransactionScope’. It works great and I would say that is something that is now in our blood.
using (var scope = new TransactionScope(TransactionScopeOption.Required)) { using (SqlConnection conn = new SqlConnection("...")) { conn.Open(); SqlCommand sqlCommand = new SqlCommand(); sqlCommand.Connection = conn; sqlCommand.CommandText = ... sqlCommand.ExecuteNonQuery(); ... } scope.Complete(); } Starting with EF6.0 we have a new way to work with transactions. The new approach is based on Database.BeginTransaction(), Database.Rollback(), Database.Commit(). Yes, no more TransactionScope.
In the followi…

GET call of REST API that contains '/'-slash character in the value of a parameter

Let’s assume that we have the following scenario: I have a public HTTP endpoint and I need to post some content using GET command. One of the parameters contains special characters like “\” and “/”. If the endpoint is an ApiController than you may have problems if you encode the parameter using the http encoder.
using (var httpClient = new HttpClient()) { httpClient.BaseAddress = baseUrl; Task<HttpResponseMessage> response = httpClient.GetAsync(string.Format("api/foo/{0}", "qwert/qwerqwer"))); response.Wait(); response.Result.EnsureSuccessStatusCode(); } One possible solution would be to encode the query parameter using UrlTokenEncode method of HttpServerUtility class and GetBytes method ofUTF8. In this way you would get the array of bytes of the parameter and encode them as a url token.
The following code show to you how you could write the encode and decode methods.