One Azure Web Role, Multiple Websites

by Brian Hitney 17. January 2012 13:27

Windows Azure has been capable of running multiple websites in a single web role for some time now, but I found myself recently in a situation with 2 separate Azure solutions and was looking to combine them to create a single deployment.   Just like in IIS, this is most often done via host headers, so requests coming in can be forwarded to the correct site.

The Goal

The fine folks at infragistics created a really cool Silverlight-based reporting dashboard for Worldmaps.  Until now, each was running as its own Azure hosted service:

image

Options to consolidate included folding the code into the Worldmaps site, which would involve actual work, or converting the site to use IIS instead of the hostable web core (HWC), which was, originally, the only way to host Azure deployments prior to version 1.3 of the SDK.  Under IIS, host headers can be used to direct traffic to desired correct site.

Preconsiderations

Inside the ServiceDefinition file, the <sites> section is used to define the websites and virtual directories, like so:

<Sites>
<Site name="Web" physicalDirectory="..\WorldmapsSite">
<Bindings>
<Binding name="HttpIn" endpointName="HttpIn" />
</Bindings>
</Site>
<Site name="Reporting" physicalDirectory="..\..\igWorldmaps\WorldmapsDemo.Web">
<Bindings>
<Binding name="HttpIn" endpointName="HttpIn" hostHeader="reporting.myworldmaps.net" />
</Bindings>
</Site>
</Sites>

Nothing too crazy in there, but I’ll talk about the paths later.

The first problem is that I was using webrole.cs file in the Worldmaps application, overriding the Run method to do some background work:

public class WebRole : RoleEntryPoint
{
public override void Run()
{
// I'm doing stuff!
}
}

The Run method is called from a different thread, and it did a lot of background processing for the site (logging data, drawing maps, etc.).   This is a great technique, by the way, to add “workers” to your website.  This is, by itself, not a problem to do under IIS or HWC, except, under the HWC version, the thread runs in the same process.   I could write to an in-memory queue via the website, and process that queue in the webrole.cs without problem, provided the usual thread safety rules are obeyed.  Likewise, the worker could read/write to an in memory cache used by the website.  Under IIS, though, the site and role are in a separate process, so it wasn’t possible to do this without re-engineering things a bit.  You don’t need to worry about this if you aren’t doing anything “shared” in your webrole.cs file.

Add the Project

In my existing Worldmaps solution, I added the infragistics “WorldmapsRporting” project by adding the project to the solution (right click the solution, and choose Add Existing Project):

image

Hook it Up

The <sites> tag (seen above) is pretty self-explanatory as it defines each site in the deployment.  For the first and main site, I didn’t provide a host header because I want it respond to pretty much anything (www, etc.).  For the second site, I give it the reporting.myworldmaps.net host header. 

Here’s the tricky part, which in retrospect seems so straightforward.  The physicalDirectory path is the path to the web project, relative to the Cloud project’s directory.   When I first created the Worldmaps solution (WorldmapsCloudApp4 is when I converted it .NET 4), I had the cloud project, the website itself, and a library project in the same directory, like so, with the cloud project highlighted:

image

So, the path the WorldmapsSite is up one level.  To get to the infragistics website, it’s up to levels, the into the igWorldmaps folder and into the WorldmapsDemo.Web folder.  We can ignore the other folders. 

DNS

The project in Windows Azure is hosted at myworldmaps.cloudapp.net, as seen from the Azure dashboard:

image

…but I own the myworldmaps.net domain.  In my DNS, I add the CNAMEs for both www and reporting, both pointing to the Azure myworldmaps.cloudapp.net URL (picture from my DNS dashboard, which will vary depending on who your DNS provider is):

image

Testing Locally

To test host headers on a local machine, you’d need to add the DNS names to your hosts file (C:\Windows\System32\drivers\etc\hosts) , like so:

127.0.0.1    myworldmaps.net
127.0.0.1    www.myworldmaps.net
127.0.0.1    reporting.myworldmaps.net

Overall, a fairly straightforward and easy way to add existing websites to a single deployment.   It can save money and/or increase reliability by running multiple instances of the deployment.

Links

http://www.myworldmaps.net

http://reporting.myworldmaps.net

Tags: ,

Azure | Tech Tips | USCloud | Worldmaps

Funniest Slide Header I’ve Seen in a Long Time…

by Brian Hitney 6. January 2012 14:10

Credit to a colleague for this slide, but for those who follow Microsoft’s cloud platform might get this reference:

slide

Tags: , ,

Azure | Microsoft

Just One More Week To Enter The Rock Paper Azure Fall Sweepstakes!

by Brian Hitney 12. December 2011 09:40

Week #3 of the Rock Paper Azure Challenge ended at 6pm EST on 12/9/2011. That means another five contestants just won $50 Best Buy gift cards! Congratulations to the following players for having the Top 5 bots for Week #3:

  1. AmpaT
  2. choi
  3. Protist
  4. RockMeister
  5. porterhouse

Just a reminder to folks in the contest, be sure to catch Scott Guthrie, Dave Campbell, and Mark Russinovich live online next Tuesday, 12/13/2011, for the Learn Windows Azure event!

RPAChallenge5

Does your bot have what it takes to win? There is one more week to try and find out, now through December 16th, 2011. Visit the Rock Paper Azure Challenge site to learn more about the contest and get started.

Remember, there are two ways to win:

Sweepstakes

To enter the sweepstakes all you have to do is enter a bot, any bot – even the pre-coded ones we provide – into the game between now and 6 p.m. ET on Dec. 16th. No ninja coding skills need – heck, you don’t even need Visual Studio or a Windows machine to participate!

RPACancun7

At 6 pm ET on Friday, December 16, 2011 the "Fall Sweepstakes" round will be closed and no new entries will be accepted. Shortly thereafter, four bots will be drawn at random for the Grand Prize (trip to Cancun, Mexico), First Prize (Acer Aspire S3 laptop), Second Prize (Windows Phone), and Third Prize (XBox w/Kinect bundle).

RPAPrizesThumbnailsTopHomePage5

Competition

BestBuyGiftCardIcon3For the type-A folks, we’re keen on making this a competitive effort as well, so each week - beginning Nov. 25th and ending Dec. 16th - the top FIVE bots on the leaderboard will win a $50 Best Buy Gift card. If your bot is good enough to be in the top five on successive weeks, you’ll take home a gift card each of those weeks too. Of course, since you’ve entered a bot, you’re automatically in the sweepstakes as well!

Note: As with past iterations of the challenge, even though you can iterate and upload updated bots for the competition, you will only be entered into the sweepstakes one time.

You know what they say… you gotta be in it to win it! Good luck to all players in week #4!

Tags: , , ,

Azure | Events | Microsoft | RPA | USCloud

Azure Camps Coming Soon!

by Brian Hitney 26. November 2011 13:55

Jim, Peter, and I are gearing up for another road trip to spread the goodness that is Windows Azure! The Windows Azure DevCamp series launched recently with a two-day event in Silicon Valley, and we’re jumping on the bandwagon for the East Region.

309b14f7-2f41-49c0-9a50-2c979d9bc97a

We have five stops planned in December, and we’re doing things a bit differently this go-round. Most of the events will begin at 2 p.m. and end at 9 p.m. – with dinner in between of course. The first part will be a traditional presentation format and then we’re bringing back RockPaperAzure for some “hands-on” time during the second half of the event. We’re hoping you can join us the whole time, but if classes or your work schedule get in the way, definitely stop by for the evening hackathon (or vice versa). By the way it wouldn’t be RockPaperAzure without some loot to give away, so stay “Kinected” to our blogs for further details on what’s at stake!

Here’s the event schedule, be sure to register quickly as some venues are very constrained on space. You’ll want to have your very own account to participate, so no time like the present to sign up for the Trial Offer, which will give you plenty of FREE usage of Windows Azure services for the event as well as beyond.

 

Registration Link Date Time
NCSU, Raleigh NC Mon, Dec. 5th, 2011 2 – 9 p.m.
Microsoft, Farmington CT Wed., Dec. 7th, 2011 2 – 9 p.m.
Microsoft, New York City Thur., Dec. 8th, 2011 9 a.m. – 5 p.m.
Microsoft, Malvern PA Mon., Dec. 12th, 2011 2 – 9 p.m.
Microsoft, Chevy Chase MD Wed., Dec. 14th, 2011 2 – 9 p.m.

Tags: , , ,

Azure | USCloud | Technology | Development | Events

Rock, Paper, Azure is back…

by Brian Hitney 22. November 2011 10:24

imageRock, Paper, Azure (RPA) is back!   For those of you who have played before, be sure to get back in the game!  If you haven’t heard of RPA, check out my past posts on the subject.   In short, RPA is a game that we built in Windows Azure.  You build a bot that plays a modified version of rock, paper, scissors on your behalf, and you try to outsmart the competition. 

Over the summer, we ran a Grand Tournament where the first place prize was $5,000!   This time, we’ve decided to change things a bit and do both a competition and a sweepstakes.   The game, of course, is a competition because you’re trying to win.  But we heard from many who didn’t want to get in the game because the competition was a bit fierce.  

Competition:  from Nov 25 through Dec 16, each Friday, we’ll give the top 5 bots a $50 Best Buy gift card.  If you’re the top bot each Friday, you’ll get a $50 gift card each Friday. 

Sweepstakes:  for all bots in the game on Dec 16th, we’ll run the final round and then select a winner at random to win a trip to Cancun.   We’re also giving away an Acer Aspire S3 laptop, a Windows Phone, and an Xbox Kinect bundle.  Perfect timing for the holidays!

Rock Paper Azure

Check it out at http://www.rockpaperazure.com!

Tags: , , ,

Azure | Development | USCloud | RPA

Geo-Load Balancing with the Azure Traffic Manager

by Brian Hitney 10. October 2011 14:18

One of the great new features of the Windows Azure platform is the Azure Traffic Manager, a geo load balancer and durability solution for your cloud solutions.  For any large website, managing traffic globally is critical to the architecture for both disaster recovery and load balancing.

When you deploy a typical web role in Azure, each instance is automatically load balanced at the datacenter level.   The Azure Fabric Controller manages upgrades and maintenance of those instances to ensure uptime.  But what about if you want to have a web solution closer to where your users are?  Or automatically direct traffic to a location in the event of an outage?   

This is where the Azure Traffic Manager comes in, and I have to say, it is so easy to set up – it boggles my mind that in today’s day and age, individuals can prop up large, redundant, durable, distributed applications in seconds that would rival the infrastructure of the largest websites. 

From within the Azure portal, the first step is to click the Virtual Network menu item.

image

On the Virtual Network page, we can set up a number of things, including the Traffic Manager.   Essentially the goal of the first step is to define what Azure deployments we’d like add to our policy, what type of load balancing we’ll use, and finally a DNS entry that we’ll use as a CNAME:

image

We can route traffic for performance (best response time based on where user is located), failover (traffic sent to primary and only to secondary/tertiary if primary is offline), and round robin (traffic is equally distributed).   In all cases, the traffic manager monitors endpoints and will not send traffic to endpoints that are offline.

I had someone ask me why you’d use round robin over routing based on performance – there’s one big case where that may be desirable:  if your users are very geography centric (or inclined to hit your site at a specific time) you’d likely see patterns here one deployment gets maxed out, while another does not.   To ease the traffic spikes to one deployment, round robin would be the way to go.  Of course, an even better solution is to combine traffic shaping based on performance with Azure scaling to meet demand.

In the above image, let’s say I want to create a failover for the Rock Paper Azure botlab (a fairly silly example, but it works).   I first added my main botlab (deployed to South Central) to the DNS names, and then added my instance deployed to North Central:

image 

From the bottom of the larger image above, you can see I’m picking a DNS name of botlab.ctp.trafficmgr.com as the public URL.  What I’d typically do at this point is go in to my DNS records, and add a CNAME, such as “www.rockpaperazure.com” –> “rps.ctp.trafficmgr.com”.

In my case, I want this to be a failover policy, so users only get sent to my North Central datacenter in the event the south central instance is offline.  To simulate that, I took my south central instance offline, and from the Traffic Manager policy report, you’d see something like this:

image

To test, we’ll fetch the main page in IE:

image

… and we’re served from North Central.  Of course, the user doesn’t know (short of a traceroute) where they are going, and that’s the general idea.  There’s nothing stopping you from deploying completely different instances except of course for the potential end-user confusion!

But what about database synchronization?   That’s a topic for another post …

Tags: , , ,

Azure | Development | USCloud | Technology

Use the Windows Azure CDN for Assets

by Brian Hitney 26. September 2011 19:28

The most common response to running stuff in the cloud (Azure, Amazon in particular) is the that it’s too expensive for the little guy.   And generally, hosting VMs when a small shared site of something similar will suffice is a tough argument.

There are aspects to Azure, though, that are very cost effective as they do “micro-scale” very well.  A good example of this is the Azure CDN, or more simply, Azure Blob Storage.   It’s effective to exchange files, it’s effective at fast delivery, and even lightweight security using shared access signatures (links that essentially only work for a period of time).    It’s durable:  not just redundant internally, but externally as well, automatically creating a backup in another datacenter.

For MSDN subscribers, you already have Azure benefits, but even going out of pocket on Blob storage isn’t likely to set you back much:  $0.15/GB of storage per month, $0.01/10,000 transactions, and $0.15/GB outbound bandwidth ($0.20 in Asia; all inbound free).  A transaction is essentially a “hit” on a resource, so each time someone downloads, say, an image file, it’s bandwidth + 1 transaction. 

Because these are micro transactions, for small apps, personal use, etc., it’s quite economical … often adding up to pennies per month.   A few typical examples are using storage to host files for a website, serve content to mobile devices, and to simply offload resources (images/JS files) from website code.

Depending on usage, the Azure Content Delivery Network (CDN) can be a great way to enhance the user experience.  It may not always be the case (and I’ll explain why) but essentially, the CDN has dozens of edge servers around the world.  While your storage account is served from a single datacenter, having the data on the edge servers greatly enhances speed.   Suppose an app on a phone is retrieving documents/text to a worldwide audience … enabling CDN puts the content much closer. 

I created a test storage account in North Europe (one of the Azure datacenters) to test this, using a small graphic from RPA:  http://somedemoaccount.blob.core.windows.net/images/dicelogo.png

Here’s the same element via the CDN (we could be using custom DNS names, but for demo purposes we’re not): http://az32338.vo.msecnd.net/images/dicelogo.png

Here’s a trace to the storage account in the datacenter – from North Carolina, really not that bad all things considered:

image

You can see we’re routed to NY, then on across the pond, and total latency of about 116ms.   And now the CDN:

image

MUCH faster, chosen not only by physical distance but also network congestion.   Of course, I won’t see a 100ms difference between the two, but if you’re serving up large documents/images, multiple images, or streaming content, the difference will be noticeable. 

imageIf you’re new to Azure and have an account, creating a storage account from the dashboard is easy.   You’d just click on your storage accounts, and enter a name/location:

image

You’d typically pick someplace close to you or where most of your users are.   To enable CDN, you’d just click the CDN link on the left nav, and enable it:

image

Once complete, you’ll see if on the main account screen with the HTTP endpoint:

image

So why wouldn’t you do this?

Well, it’s all about cacheability.   If an asset is frequently changing or infrequently used, it’s not a good candidate for caching.   If there is a cache miss at a CDN endpoint, the CDN will retrieve the asset from the base storage account.  This will incur an additional transaction, but more importantly it’s slower than if the user just went straight to the storage account.  So depending on usage, it may or may not be beneficial. 

Tags: , , ,

Azure | USCloud | Tech Tips

Azure and Phone … Better Together

by Brian Hitney 21. September 2011 17:58

We had an excellent time presenting today’s Windows Phone Camp in Charlotte. Thank you to everyone who attended. Here are some resources and major points of today’s “To the cloud…” session.

First, here is the slide deck for the presentation. 

Next, download the Windows Azure Toolkit for Windows Phone. This contains both the sending notifications sample, and the Babelcam application. Note that there are quite a few setup steps – using the Web Platform Installer is a great way to make all of this easier.

The key takeaway that I really wanted to convey: while the cloud is most often demonstrating massive scale scenarios, it’s also incredibly efficient at micro scale. The first scenario we looked at was using Azure Blob Storage as a simple (yet robust) way to host assets. Think of Blob Storage as a scalable file system with optional built in CDN support. Regardless of where your applications of hosted (shared host, dedicated hosting, or your own datacenter), and regardless of the type of application (client, phone, web, etc.) the CDN offers a tremendously valuable way to distribute those resources.

For MSDN subscribers, you already have access so there’s no excuse to not use this benefit. But even if you had to go out of pocket, hosting assets in Azure is $0.15/GB per month, + $0.01/10,000 transactions, + $0.15/GB outbound bandwidth (inbound is free). For small applications, it’s almost free. Obviously you need to do the math for your app, but consider hosting 200MB in assets (images, JS files, XAPs, etc.), a million transactions a month with several GB of data transfers: it’s very economical at the cost of a few dollars / month.

In the second demo, we looked at using Azure Queues to enhance the push notification service on the phone. The idea being that we’ll queue failed notifications, and retry them for some specified period of time. For the demo, I only modified the raw notifications. In PushNotificationsController.cs (in toolkit demo above), I modified SendMicrosoftRaw slightly:

[HttpPost]
public ActionResult SendMicrosoftRaw(string userId, string message)
{
if (string.IsNullOrWhiteSpace(message))
{
return this.Json("The notification message cannot be null, empty nor white space.",
JsonRequestBehavior.AllowGet);
}

var resultList = new List<MessageSendResultLight>();
var uris = this.pushUserEndpointsRepository.GetPushUsersByName(userId).Select(u => u.ChannelUri);
var pushUserEndpoint = this.pushUserEndpointsRepository.GetPushUsersByName(userId).FirstOrDefault();

var raw = new RawPushNotificationMessage
{
SendPriority = MessageSendPriority.High,
RawData = Encoding.UTF8.GetBytes(message)
};

foreach (var uri in uris)
{
var messageResult = raw.SendAndHandleErrors(new Uri(uri));
resultList.Add(messageResult);

if (messageResult.Status.Equals(MessageSendResultLight.Error))
{
this.QueueError(pushUserEndpoint, message);
}
}

return this.Json(resultList, JsonRequestBehavior.AllowGet);
}

Really the only major change is that if the messageResult comes back with an error, we’ll log the error. QueueError looks like this:

private void QueueError(PushUserEndpoint pushUser, string message)
{
var queue = this.cloudQueueClient.GetQueueReference("notificationerror");

queue.CreateIfNotExist();
queue.AddMessage(new CloudQueueMessage(
string.Format("{0}|{1}", pushUser.ChannelUri.ToString(), message)
));
}

We’re simply placing the message on the queue with the data we want: you need to get used to string parsing with queues. In this case, we’ll delimit the data (which is the channel URI and the message of the notification) with a pipe character. While the channel URI is not likely to change, it’s a better approach to store the username and not the URI in the message, and instead do a lookup of the current URI before sending (much like the top of SendMicrosoftRaw does), but for the purposes of the demo is fine.

When we try sending a raw notification when the application isn’t running, we’ll get the following error:

image_thumb3

Typically, without a queue, you’re stuck. Using a tool like Cloud Storage Studio, we can see the notification is written to the failure queue, including the channel URI and the message:

image_thumb5

So, now we need a simple mechanism to poll for messages in the queue, and try to send them again. Because this is an Azure webrole, there’s a way to get a “free” thread to do some processing. I say free because it’s invoked by the Azure runtime automatically, so it’s a perfect place to do some background processing outside of the main site. In Webrole.cs, you’ll see there is no Run() method. The base WebRole Run() method does nothing (it does an indefinite sleep), but we can override that. The caveat is, we never want to exit this method. If an exception bubbles out of this method, or we forget to loop, the role will recycle when the method exits:

public override void Run()
{
this.cloudQueueClient = cloudQueueClient ??
GetStorageAccountFromConfigurationSetting().CreateCloudQueueClient();
var queue = this.cloudQueueClient.GetQueueReference("notificationerror");
queue.CreateIfNotExist();

while (true)
{
Thread.Sleep(200);

CloudQueueMessage message = queue.GetMessage(TimeSpan.FromSeconds(60));

if (message == null) continue;

if (message.DequeueCount > 60)
{
queue.DeleteMessage(message);
continue;
}

string[] messageParameters = message.AsString.Split('|');

var raw = new RawPushNotificationMessage
{
SendPriority = MessageSendPriority.High,
RawData = Encoding.UTF8.GetBytes(messageParameters[1])
};

var messageResult = raw.SendAndHandleErrors(new Uri(messageParameters[0]));

if (messageResult.Status.Equals(MessageSendResultLight.Success))
{
queue.DeleteMessage(message);
}
}
}

What this code is doing, every 200 milliseconds, is looking for a message on the failure queue. Messages are marked with a 60 second timeout – this will act as our “retry” window. Also, if we’ve tried to send the message more than 60 times, we’ll quit trying. Got to stop somewhere, right?
 
We’ll then grab the message from the queue, and parse it based on the pipe character we put in there. We’ll then send another raw notification to that channel URI. If the message was sent successfully, we’ll delete the message. Otherwise, do nothing and it will reappear in 60 seconds.
 
While this code is running in an Azure Web Role, it’s just as easy to run in a client app, service app, or anything else. Pretty straightforward, right? No database calls, stored procedures, locking or flags to update. Download the completed project (which is the base solution in the toolkit plus these changes) here (note: you’ll still need the toolkit): 

The final demo was putting it all together using the Babelcam demo – Azure queues, tables, notifications, and ACS.

Questions or comments? Let me know.

Tags: , , ,

Azure | Windows Phone 7 | USCloud | Events

RPA Grand Tournament Complete!

by Brian Hitney 14. July 2011 20:36

We had a GREAT time running the RockPaperAzure Grand Tournament Wednesday.  We had a total of 302 players from around the world, and the top players in the finals were:

image

We saw some amazing strategies, and learned a lot along the way.  We intend to keep the site running with more contests along the way – if you have any interest in running a competition for a user group, conference, or other activity, we’d be happy to create a round for you on the site.  Contact us for info.

Server Load

Nothing exposes bugs faster than a system under load!  And load it had.  Here’s an example of the load on the game engine in terms of the number of bots submitted during the competition:

image

Now, that’s just a linear look at submissions.  With over 3000 bots flooding in (mostly during the afternoon), we kept our game engine farm quite busy.   As you may have seen in our webcasts, as the number of players increases, the number of player matches goes up significantly:

image

The above graph illustrates the number of matches to players – and this only goes up to 50 players.  Expand this to 300 players, and the load is tremendous.  (That’s one of the excellent points about Azure – we’re able to hit a button and handle the load.)

We’re going to continue some experimental open rounds so stay tuned!

Tags: , ,

Azure | RPA | USCloud

Top Reasons for Bot Rejection

by Brian Hitney 7. July 2011 21:06

Just a quick tip for those in the Grand Tournament.  There are 2 very common reasons we’re seeing bots get rejected – we’ll call it the red text of death that appears when you submit a bot, but it fails code analysis.  If all you see is “Bot Successfully Uploaded,” then move along, nothing to see here.

The most common are coders adding debugging statements into their code.  We do block the Diagnostics namespace (among a few others), so it’s quite likely any debugging code will trigger a failure.   If you’re deep into a bot with a lot of debug code, I recommend an #ifdef around these sections to remove them from release builds.

The second most common reason are locks.  Locks, as you likely know, are syntactical sugar around a Monitor, which resides in the System.Threading namespace.  We don’t allow that, either.   But many may ask, “Why no locks?  Is it not a good practice to do this around a critical section of code?”   Not in this case.  Your bot shouldn’t be using statics since we can’t guarantee when or how many instances of your bots will be loaded at any given time, and I can guarantee this will burn you.   Your bot also can’t create threads, so locking is irrelevant in this case and would only slow things down.

In many cases, these errors are triggered in bots where folks are rolling their own random number generator.  While you don’t have to use it, we highly recommend you use the Moves.GetRandomNumber() method.  It works the same way, but we guarantee unique generation for bots and we do the locking in the engine to ensure this.  There’s a fun story behind that one.

Good luck!

Tags: , ,

Azure | RPA | USCloud

your host...

Brian Hitney
Developer Evangelist
Microsoft Corp.

About Me

My Worldmap