When we last left off, we had a web application spinning away in the cloud, and a local console application watching it and reacting to changes in demand. Reactions that were specified by a set of rules. Let’s talk about those rules. Constraints. The first set of rules this application answered to were the constraints. Here is what they looked like: <constraintRules>
<rule name="default" enabled="true" rank="1" description="The default constraint rule">
<actions>
<range min="1" max="4" target="AutoscalingApplicationRole"/>
</actions>
</rule>
</constraintRules>
Pretty basic. We have one role, the “AutoscalingApplicationRole”, and we have decided to have it live within a range of 1 to 4. This rule does not adjust, but instead, set’s limits on what other rules can do. It has a rank, so you can have you can specify other sets of constraints, perhaps based on time or date, to allow for deviations from this set. But for now, let’s keep it simple. In the real world, you would probably use the minimum to set a lower end SLA. A common value might be a 2, to prevent the reactive rules from ever taking you down to 1 role. The maximum is often used to keep a rule from driving the cost up, setting an upper limit to prevent you waking up one morning and find a bill for hundreds of instances you didn’t expect.
So, here we have the range we want our application to live inside. This is good for our investigation and testing. Next, let’s take a look at the reactive rules. These rules are what you use to react (hence reactive rules) to changing demands on your application. The HOL has two simple rules. One that looks at a queue depth, and one that looks at a performance counter that reports cpu utilization. the XML in the rules file looks like this:
<reactiveRules>
<rule name="ScaleUp" rank="10" description="Scale Up the web role" enabled="true">
<when>
<any>
<greaterOrEqual operand="Length_05_holqueue" than="10"/>
<greaterOrEqual operand="CPU_05_holwebrole" than="65"/>
</any>
</when>
<actions>
<scale target="AutoscalingApplicationRole" by="1"/>
</actions>
</rule>
<rule name="ScaleDown" rank="10" description="Scale down the web role" enabled="true">
<when>
<all>
<less operand="Length_05_holqueue" than="5"/>
<less operand="CPU_05_holwebrole" than="40"/>
</all>
</when>
<actions>
<scale target="AutoscalingApplicationRole" by="-1"/>
</actions>
</rule>
</reactiveRules>
<operands>
<performanceCounter alias="CPU_05_holwebrole" performanceCounterName="\Processor(_Total)\% Processor Time" source="AutoscalingApplicationRole" timespan="00:05:00" aggregate="Average" />
<queueLength alias="Length_05_holqueue" queue="hol-queue" timespan="00:05:00" aggregate="Average"/>
</operands>
These rules are currently contained in a file called rules.xml, that is in the root of the console application. The console app, starts up, grabs the rules and starts watching the 2 operands. When it detects a rule has been satisfied, it performs the desired action. (here, scale up or down my 1).
But I want to host the autoscaler in the cloud. For my first trick, I will move the rules (and another file called services.xml) to azure blob storage. Look for part 3.