RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Automated Resource Management of Cloud-Based Applications : Page 2

For better performance, applications should be capable of handling and normalizing variations so that users aren't affected.


a) Averaging the monitored values to remove frequent see-saw variations

Let’s take a use case where we are monitoring the CPU utilization of the application servers on which the web application is hosted. The monitoring tool Hyperic is configured to output the metric data every minute. Values coming from the tool might contain unwanted spikes due to certain reasons. So before reaching to any conclusion, we need to process this data to get the valid metric value. In this example, we are averaging the data every 5 minutes to remove the unwanted spikes.

b) Drool Engine

Once we get the processed data by averaging, we will pass it to the Drool engine. It takes this processed value as an input and suggests necessary action that needs to be initiated. Drool is a rule engine and consists of a simple drool file. We define the rules under which an action needs to be initiated in this file. When the conditions are met, the corresponding actions configured in the file are processed. Below is the drool file and the corresponding java code to invoke it.

import org.apache.log4j.Logger;
import org.poc.cloud.Action;

rule "Increase VM Rule"   
    	$metricValue: Double()
    	logger.info("Cpu-Utilization shoot beyond upper-threshold");
	Action action=new Action();

rule " Decrease VM Rule "   
    	$metricValue: Double()
    	logger.info("Cpu-Utilization goes below the lower-threshold");
	Action action=new Action();

function double checkValue(Double num1) {
  	return num1;
Figure 4 : Optimizer.drl file

Java code to call rule adapter which will internally invoke drools file.

	RuleInput ruleInput;
	ruleInput=new RuleInput();
ruleInput.setMetricInputValue(0.62);//averaged value as an input to the optimizer
RuleAdapter ruleAdapter;
		ruleAdapter = (RuleAdapter) getContext().getBean("ruleAdapter");		
		ruleAdapter.runRules(new String[] {"Optimizer.drl"},
					new Object[] {ruleInput});

Figure 5: Java code to call rule adapter
import org.drools.definition.KnowledgePackage;
Import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;

public class RuleAdapter {
    static Logger logger = Logger.getLogger(RuleAdapter.class.getName());
    public RuleAdapter() {

    public void runRules(String[] rules,
                         Object[] facts) throws Exception {

        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

        for ( int i = 0; i < rules.length; i++ ) {
            String ruleFile = rules[i];
            logger.info( "Loading file: " + ruleFile );
            kbuilder.add( ResourceFactory.newClassPathResource( ruleFile,
            		RuleAdapter.class ),
                                  ResourceType.DRL );

        Collection<KnowledgePackage> pkgs = kbuilder.getKnowledgePackages();
        kbase.addKnowledgePackages( pkgs );
        StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

        for ( int i = 0; i < facts.length; i++ ) {
            Object fact = facts[i];
            logger.info("Inputting values to drl file: " + fact );
            ksession.insert( fact );

Figure 6: Rule adapter class which will invoke drools file.

The RuleAdapter class will invoke the rule file with RuleInput object as an input to it. The RuleInput object is composed of metric value and metric name property.

Optimizer.drl file:

This drool file contains two rules:

    1. Increase VM Rule -- When the metric value exceeds the upper-threshold level.
    2. Decrease VM Rule -- When the metric value crosses the lower-threshold level.

1) Increase VM Rule During peak hours when the load increases, the CPU utilization also increases. Over-utilization of CPU would results in poor performance which might drift away the users from the application. Therefore, we should be able to handle such situations to meet the SLOs of the applications. We should add more application servers in the environment after utilization crosses the permissible value.  This permissible value is configured in a drool file. Let’s assume the threshold value for utilization is 60%. So in a drool file, we have specified a rule to add one virtual machine when the metric value goes beyond 60% by calling increaseVM() action.

2) Decrease VM Rule: During off-peak hours when the load is very low, the servers would be under-utilized. If the average utilization of servers goes below a specified threshold, virtual machines could be released to allow other instances takeover its load. Here, we have configured lower threshold value for utilization as 30%. So, in drool file we have specified a rule to decrease one virtual machine whenever the metric value goes below 30% by calling decreaseVM() action.

Step 3: Action Execution

Based on the metric value, an action is invoked by the drool file according to the thresholds set. If CPU utilization goes beyond certain level, then we should add one or more VMs to handle the load. Similarly, if it goes below certain threshold then extra VMs should be removed.

Figure 7: Action Engine.

Based on the optimized value, the Optimizer suggests an action to the Action engine. To accomplish the same, the actions interact with the Eucalyptus (using its API) to create or destroy virtual machines accordingly (refer to figure 7).

Let’s dive in to the code to see how to achieve the same programmatically. We can see from Figure 4( Optimizer.drl file), there is an Action class which gets invoked based on the value. There are increaseVM() and decreaseVM() methods in that class.

Before making calls to Eucalyptus API, we need to set some system variables.

Figure 8: Setting System variables.

increaseVM() -- This method is called when the value crosses the permissible upper threshold limit. It creates one more virtual machine.

public void increaseVM(){ 
String eucaURL = "";

ClientPool cp = Defaults.getOneoffClientPool(eucaURL);
	BasicClient client = (BasicClient) cp.borrowObject();
	EucalyptusMessage request = new RunInstancesType();			
	request.setProperty("kernelId", "KERNEL_ID_OF_EUCALYTPTUS_SYSTEMS");
	request.setProperty("instanceType", "SIZE_OF_INSTANCE_TO_CREATED");
	request.setProperty("keyName", "KEY_NAME_TO_ADD_MORE_SECURITY");
	request.setProperty("imageId", "IMAGE_NAME");
	request.setProperty("minCount", "MINIMUM_COUNT_OF_VM_TO_BE_CREATED");
	request.setProperty("maxCount", "MAXIMUM_COUNT_OF_VM_TO_BE_CREATED");
	request.setProperty("addressingType", "ADDRESSING_TYPE");
	EucalyptusMessage reply = client.send(request) ;
	System.out.println("RunInstancesType reply = " + reply);
Figure 9: increaseVM() method code snippet.

The code is self-explanatory. To create a new VM, we have to follow the above code and pass some parameters.
'Instance Type' refers to size of the VM to be created. Some of the allowed values are - 'm1.small', 'c1.medium',' m1.large', etc.
We can create more than one VM in single request by specifying the maximum count.
decreaseVM() -- This method is called when the value goes below the lower threshold. In this case, we terminate a VM.

public void decreaseVM(){

String eucaURL = "";

ClientPool cp = Defaults.getOneoffClientPool(eucaURL);
	BasicClient client = (BasicClient) cp.borrowObject();

	EucalyptusMessage request = new TerminateInstancesType();

	List<String> instancesToBeTerminated = new ArrayList<String>();	
	request.setProperty("instancesSet", instancesToBeTerminated);

	EucalyptusMessage reply = client.send(request) ;

		System.out.println ("Selected Instances terminated successfully!");
	}else {
		System.out.println ("Selected Instances not terminated !");
	System.out.println("TerminateInstancesType reply:: " + reply);

Figure 10: decreaseVM() method code snippet.

In this method, we pass the instance id of the VM to be terminated as a EucalyptusMessage object. Here again, we can terminate more than one VM in a single request.

We have used Hyperic for collecting data, but there are lots of other tools in the market.

Similarly, for cloud computing environments, there are providers like VmWare, Platform Computing, etc. who offer features like hot update of VM, hot migration of VM from one host to another, etc. Appropriate provider can be chosen based on requirements.


Here, we have illustrated how we can achieve a simple dynamic resource management in a cloud computing environment. Increasing or decreasing the VM count dynamically based on CPU utilization is one of the solutions for managing the resources dynamically. In real scenarios, the rules for increasing or decreasing the VM count will be more complex and take a multiplicity of factors into consideration. Further, there could be  several other reasons for poor performance of applications like increased thread count, heap memory size, poor application design, network overheads,  etc. which can be optimized by taking appropriate actions like pooling valuable resources, optimizing I/O operations and other solutions.  Mere addition of Virtual Machines instances will not solve such problems. Therefore, finding an optimal solution is a big challenge in itself and should be well researched before finalizing any action.

Akansha Jain works as a Technical Analyst at SETLabs, the R&D division at Infosys Technologies Ltd. She has a number of years' experience in Java and Java EE application development, Eclipse plugin architecture, software factory, Web 2.0, and cloud computing.
Email AuthorEmail Author
Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date