Scaling PHP Applications on Windows Azure Part II: Role Management

Author: Ben Lobaugh <ben@lobaugh.net>

Date: Monday, May 23, 2011, 4:30:41 PM

Tags: Tutorial, Scaling, Performance Metrics

Table of Contents

Note:This article pertains to the CodePlex SDK initially released late 2009. The Windows Azure team has since then released a newer version of the Azure SDK for PHP on Github. Please refer to the Windows Azure PHP Developer Center for documentation on this more recent version of the SDK.

Please stay tuned and come back here regularly as we are working on refreshing the tutorials to deliver up to date and useful content for our PHP developers.

Recommended pre-read

Synopsis

This is part II in a series of articles on scaling PHP applications on Windows Azure. I will be picking up right where I left off from part I of this series so if you have not read part I already I highly encourage you to do so as some of the referenced code was given in that article. We will be building our code library through each article.

In this article I will show you how to create a certificate for your Windows Azure account, connect to the Service Management API, and update role instance counts on a per role name basis. I am assuming you still have all the necessary files for working with Windows Azure from the previous article in this series.

Create the certificate for the Windows Azure Service Management API

The Windows Azure Service Management API allows us to connect to and manage service deployments (and their roles) on Windows Azure. In order to connect to the Service Management API we need to create a certificate for the server, and also one for the client. Each time the client makes a call to the Management API it must provide the client certificate to the server to verify the client's right to make changes, and/or read account information. We will need to create two certificates, a .cer for the server, and a .pem for the client.

Creating a .cer is easy with the makecert command, however generating the .pem from the .cer is a bit more complicated and makecert cannot handle it. I used OpenSSL which you can download for Windows and run in a console.

For a description of openssl parameters see the documentation at: http://www.openssl.org/docs/apps/openssl.html

Create .pem

openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mycert.pem -out mycert.pem

Create .cer

openssl x509 -inform pem -in mycert.pem -outform der -out mycert.cer

Upload the server key

Now you need to upload the .cer to your Windows Azure account. As soon as you upload the server key you may start using the Management API from your applications.

  • Using the Legacy Portal
    • Select the project
    • Click the Account tab
    • Click "Manage My API Certificates"
    • Browse and Upload the new certificate
  • Using the New Portal
    • Select "Hosted Services, Storage Accounts & CDN"
    • Choose "Management Certificates"
    • Click "Add Certificate"

Additional Reading

To learn more about generating certificates here is some additional reading

Setup a connection to the Service Management API

Wondering what to do with the .pem file we created in the last section? Put it in the folder with the rest of the code for this project. The Service Management API requires the client to prove it has the right to make requests against the API. In order to do that we have to supply the API with the .pem file with each request.

Note: This is not something you would want to do on a web role! With your .pem file sitting within public reach you are sure to have your account compromised. When we put all the code together in part III of this series you will see that the .pem can exist in the project root and still be secure from sticky fingers with a worker role.

Now that we have our certificates setup it is time to start consuming the Service Management API from our applications.

Create the connection settings

Our first step is to update our ever-inclusive include.php file with the settings necessary for the connection, so open up your include.php file.

In the constant definition section you will need to add the following

define('SUB_ID', '<your subscription id>');
define('CERT_KEY', '<your certificate thumbprint>');
define('CERT','<name of your .pem file>');

Locate your Subscription ID

  • Using the Legacy Portal
    • Select the project
    • Click the Account tab
    • Locate Subscription ID under the Support Information Header
  • Using the New Portal
    • Select "Hosted Services, Storage Accounts & CDN"
    • Choose "Hosted Services"
    • Select the name of the subscription
    • Locate Subscription ID in the Properties pane

Locate the certificate thumbprint

  • Using the Legacy Portal
    • Select the project
    • Click the Account tab
    • Click "Manage My API Certificates"
    • Select the desired certificate and locate the Thumbprint column
  • Using the New Portal
    • Select "Hosted Services, Storage Accounts & CDN"
    • Choose "Management Certificates"
    • Select the desired certificate
    • Locate Thumbprint in the Properties pane

Setup the management object

Before we do this I need to say a little more about local versus cloud management, and how what you thought about the storage connections does not apply. With a storage connection you have the option to use storage in two modes: through the local development storage, or in the cloud. The Windows Azure team has provided all the hooks you need to make it seamless to switch between local storage and the cloud without worrying about breaking your calls. Not so with the Service Management API. There is no way currently to do things like pulling deployment information and updating role instance counts. If you do not have an account on Windows Azure already this is the point at which you need to go create one. Microsoft frequently offers free, limited trials so you can test the platform. One of the free trial accounts provides access to everything you need to complete the demos in this series.

Now back to the task at hand. You need to pull in one additional object which we can then instantiate and then we get down to the fun stuff!

require_once('Microsoft/WindowsAzure/Management/Client.php');
    $client = new Microsoft_WindowsAzure_Management_Client(
            SUB_ID, 
            CERT, 
            CERT_KEY
    );

Changing role instance counts

Changing the number of running roles is surprisingly easy. One method call from the client fires off a request to the Service Management API to update the counts and presto! Role instances counts are updated. Let me lay out the method call then I will describe the various pieces you will need to make it work.

$client->setInstanceCountBySlot(AZURE_SERVICE, 'production', 'WebRole', <NUMBER OF NEW ROLE COUNT);

Here are the parameters in order:

  • Service name (this is the domain prefix you chose when setting up the service)
  • Staging or production
  • Name of the role you want to update (Currently the PHP Command-line Tools automatically name the web role "WebRole"
  • Integer representing the number of roles you want running

Things to be aware of when changing role counts

Windows Azure makes it very easy to spin up new roles, tear down roles, and do all other sorts of interesting things, but along with the ease of deployment comes several caveats which you must be aware of and plan for accordingly.

Blocking until operations complete

Calling the setInstanceCountBySlot method fires off an asynchronous call to the Service Management API; this has to critical import to your application's behavior. First, the lines of code following the method call must not be dependent on the operation having completed. Second you may not be able to make another API call until this one has completed. Luckily there is a way to check the status of your operations and block you application from proceeding until the operation has completed. The following code will check the operation status once per second. If the operation is still in progress it will pause execution for another second and check again.

$status = $client->getOperationStatus($lastRequestId);

while ($status->Status == 'InProgress') {
    echo '.';
    $status = $client->getOperationStatus($lastRequestId);
    sleep(1);
}

Spinning up new instances takes time

When you add a new instance of any kind Window Azure does a lot of work behind the scenes for you, creating a new server image, installing your application, booting, patching, etc. All the actions Windows Azure does in creating your new instances simply take time. You need to be aware of this and plan your resources accordingly. Depending upon how active your service is I personally recommend keeping at least one extra instance on hand to take up the slack when you spike until another role can be spun up to even out the load. If you have a highly active site, or large swings in use, you may want to keep even more extra roles available at all times. Let me give you a couple scenarios that will help you envision the need to know when you need extra roles.

  1. You have popular site that has regular updates a noon (or any specific time) every day which brings in a large amount of traffic until 5 P.M.
    1. Because you know your traffic spikes each day at noon you could spin up new roles at 11 A.M. Spinning up your roles an hour early allows time for the roles to start and a little flex time for users that come visit your site early.
    2. Because you also know your traffic lessens at 5 P.M. you can start reducing the number of running roles after 5 P.M.
  2. You have a high traffic site that periodically and semi-predictably has large quick spikes in usage
    1. Keep a few extra roles available for those quick spikes. Spin up new roles to replace the number of extra roles that become loaded during the spikes.
  3. You have a site with large predictable traffic patterns
    1. Keep a few extra roles running as a buffer while new instances are spinning up. When you begin to detect a traffic increase the extra roles that were running should be adequate to handle the new traffic until additional roles are available to mitigate the increased flow.

These are just a few possible examples that may cause you to spin up new instances. Due to the highly diverse nature of applications and their resource needs you must understand how your application interacts not only with resources such as CPU and memory, but also now much traffic your application, the server, and the network can handle. After you gather the profiling information on your application you can begin setting up rules to scale your application

Something that you need to keep note of is your "extra" roles are not sitting around doing nothing. The Windows Azure load balancer uses a round robin approach to load balancing that spreads the work load across the running roles. When you think of them as extra roles you should look at it from the perspective that you have more roles running than you need to handle the average load of your application.

What's Next?

· Scaling PHP Applications on Windows Azure Part III: Performance Monitor

 
blog comments powered by Disqus