← Back to overview
January 22, 2013 · memcache Microsoft Azure Web Sites Node.js Windows Azure Caching

Improve performance of your Node.js Web Site with Windows Azure Caching (Dedicated Role)

If your application is running in a Cloud Service (Web/Worker Role) it's very easy add caching to your application by using Windows Azure Caching:

Windows Azure Caching introduces a new way to perform caching by using a portion of the memory of the virtual machines that host the role instances in your Windows Azure cloud services (also known as hosted services). You have greater flexibility in terms of deployment options, the caches can be very large in size and have no cache specific quota restrictions.

The .NET libraries depend on a library which is specific to Cloud Services, which makes them unable to use in Windows Azure Web Sites. This restriction applies to the official Windows Azure Caching libraries for .NET. But Windows Azure Caching also supports the memcache protocol, this means you can use it from any environment supporting memcache like Node.js, php, …

Let's see how we can configure the memcache protocol in Windows Azure Caching, open it up for Windows Azure Web Sites and call it from a Node.js application.

Memcache support for Windows Azure Caching

We start by creating a new Dedicated Cache Worker Role as described here. Once this is done we'll add support for the memcache protocol by using the Memcache Server Gateway. TheClient Shim is not an option here since it requires an installation on the consumer side: in our case this is the Web Site and Web Sites don't support running custom installations at the moment (remember that you're running in a shared hosting model).

Setting up the Memcache Server Gateway is pretty easy: add an endpoint called memcache_default to your Cache Worker Role (you can choose the port):

Allowing access from your Web Site

When using Windows Azure Caching within a Cloud Service you typically set the endpoint type to Internal. But since the Web Site is not part of the Cloud Service you'll need to change the endpoint to Input. It's important to know that, by changing the type to Input, your Web Site will be able to connect to the endpoint just like everyone else with an internet connection.

Chances are pretty small that anyone will find this endpoint (by guessing/scanning the IP+port), connect to it, find out that it can be used by a memcache client and do something with the data. But it's better to be safe than sorry so here is what you can do: you can use the WindowsAzure.IPAddressRestriction library to restrict access to the Worker Role. If you look at the Examples on GitHub there's an example that shows you how to restrict access to your Worker Role endpoint(s) based on hostnames:

public class WebRole : RoleEntryPoint  
    private IPAddressRestrictionManager restrictionManager;
    private List<Restriction> hostnameRestrictions;

    public override bool OnStart()
        if (RoleEnvironment.IsAvailable && !RoleEnvironment.IsEmulated)
            RoleEnvironment.Changing += OnRoleEnvironmentChanging;

        return base.OnStart();

    private void AddAllowedHostnames()
        if (restrictionManager == null)
            restrictionManager = new IPAddressRestrictionManager();

        // First time we run the method.
        if (hostnameRestrictions == null)
            // Create a list which holds the previously created restrictions.
            hostnameRestrictions = new List<Restriction>();

            // Schedule refresh.
            var hostnamesRefreshTimer = new System.Timers.Timer(5 * 60000);
            hostnamesRefreshTimer.Elapsed += (s, e) => { AddAllowedHostnames(); };

        // Loop each configured hostname.
        var hostNames = RoleEnvironment.GetConfigurationSettingValue("HostnamesAllowedToAccessPort10100");
        foreach (string hostName in hostNames.Contains(",") ? hostNames.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries) : new string[] { hostNames })
                System.Diagnostics.Trace.WriteLine("Processing: " + hostName);

                // Get each IP Address from the hostname.
                var ipAddresses = System.Net.Dns.GetHostAddresses(hostName);
                foreach (var ipAddress in ipAddresses)
                    if (!hostnameRestrictions.Any(o => o.Port == "10100" && o.RemoteAddress == ipAddress.ToString()))
                        hostnameRestrictions.Add(new Restriction() { Port = "10100", RemoteAddress = ipAddress.ToString(), NameSuffix = hostName });
            catch (Exception ex)

        // Clean up old rules.

        // Disable all standard rules on port 10100.

        // Create new rules mathing the hostname.
        restrictionManager.Apply(hostnameRestrictions.ToArray(), false);

Once you've set up this code in your Worker Role you can configure the hostnames in your Service Configuration:

<?xml version="1.0" encoding="utf-8"?>  
<ServiceConfiguration serviceName="..." xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="3" osVersion="*" schemaVersion="2012-10.1.8">  
  <Role name="...">
    <Instances count="1" />
      <Setting name="HostnamesAllowedToAccessPort10100" value="mynodeapp.azurewebsites.net,mynodeapp.com" />

Using Windows Azure Caching from your Node.js Web Site

So we've set up Windows Azure Caching, added memcache support and made sure that (only) our Web Site can access the cache. Let's get started on our Node.js application. The application will use the node-memcache library to access Windows Azure Caching through the memcache protocol. Here is the sample application:

var memcache = require('./memcache');

var client = new memcache.Client(10100, 'mycachecloudservice.cloudapp.net');  

var http = require('http')  
http.createServer(function(req, res) {

    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.write(' <body>');

    client.get('somekey', function(error, result) {
        if (result != null) {
            res.write('     <p>Fetched somekey from cache: ' + result + '</p>');
            res.write(' </body>');
        else {
            var value = 'This is the cached value at ' + new Date().toISOString();
            client.set('somekey', value, function(error, result) {
                res.write('     <p>Updated somekey in cache to: ' + value + '</p>');
                res.write(' </body>');

The code ispretty straight forward. We reference the library, create the client and connect to the endpoint we opened in the Cloud Service. The get and set methods allow you interact with the cache. If you access the page the first time you'll see that the value is added to the cache:

Each subsequent request will get the data from the cache:

And that's about it.You're all set up to use Windows Azure Caching through the memcache protocol which can drastically improve performance of your site.


  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket
Comments powered by Disqus