Windows Azure – Dynamically scaling your application

When you have your service running on Windows Azure, the least thing you want is monitoring every now and then and decide if there is a necessity for specific actions based on your monitoring data. You want the service to be, in some degree, self-manageable and decide on its own what the necessary actions should take place to satisfy a monitoring alert. In this post, I’m not going to use Service Management API to increase or decrease the number of instances, instead I’m going to log a warning, but in a future post I’m going to use it in combination with this logging message, so consider this as a series of posts with this being the first one.

The most common scenario is dynamically increase or decrease VM instances to be able to process more messages as our Queues are getting filled up. You have to create your own “logic”, a decision mechanism if you like, which will execute some steps and bring the service to a state that satisfies your condition because there is no out-of-the-box solution from Windows Azure. A number of companies have announced that their monitoring/health software is going to support Windows Azure. You can find more information about that if you search the internet, or visit the Windows Azure Portal under Partners section.

In the code below I’m monitoring the messages inside a Queue at every role cycle:

1: CloudQueue cloudQueue = cloudQueueClient.GetQueueReference("calculateP");
3: cloudQueue.CreateIfNotExist();
4: cloudQueue.FetchAttributes();
6: /* Call this method to calculate your WorkLoad */
7: CalculateWorkLoad(cloudQueue.ApproximateMessageCount);

and this is the code inside CalculateWorkLoad:

1: public void CalculateWorkLoad(int? messages)
2: {
3: /* If there are messages, find the average of messages
4: available every X seconds
5: X = the ThreadSleep time, in my case every 5 seconds */
6: if (messages != null)
7: average = messages.Value / (threadsleep / 1000);
9: DecideIncDecOfInstances(average); 10: }

Note that if you want to get accurate values on queue’s properties, you have to call FetchAttributes();

There is nothing fancy in my code I’m just finding an average workload (number of messages in my Queue) every 5 seconds and I’m passing this value at DecideIncDecOfInstances(). Here is the code:

1: public void DecideIncDecOfInstances(int average)
2: {
3: int instances = 2;
5: /* If my average is above 1000 */
6: if (average > 1000)
7: OneForEveryThousand(average, ref instances);
8: WarnWeNeedMoreVM(instances);
9: }

OneForEveryThousand count is actually increasing the default number of instances, which is two (2), by one (1) for every thousand (1000) messages in Queue’s average count.

This is the final part of my code, WarnWeNeedMoreVM which logs our need for more or less VM’s.

1: public void WarnWeNeedMoreVM(int instances)
2: {
3: if (instances == 2) return;
5: Trace.WriteLine(String.Format("WARNING: Instances Count should be {0} on this {1} Role!",
6: instances, RoleEnvironment.CurrentRoleInstance.Role.Name), "Information");
7: }

In my next post for these series, I’m going to use the newly released Service Management API to upload a new configuration file which increases or decreases the number of VM instances in my role(s) dynamically. Stay tunned!