Hosting options for NServiceBus on Azure – Web roles & web workers

Understanding webroles

Up until now I’ve only discussed worker roles, deliberatly, as they are relatively straight forward to use in combination with NServiceBus.

Webroles however are a bit different when it comes to NServiceBus hosting, not that it is per se more difficult to do so, but you need to understand how webroles work to avoid weird effects when running NServiceBus inside them.

There are 2 flavors of webroles, Hosted Web Core and Full IIS, and it makes a difference to host NServiceBus depending on which one you use as their process model differs quite a lot.

Web roles models

If you’re webrole uses HWC there will be only 1 process hosting your assemblies, representing the web role. In this scenario there is no difference between a web and worker and you can simply host an NServiceBus endpoint inside of it the same way.

But in Full IIS mode, which is the default, you need to know that 1 webrole project will result in 2 processes which share the same assemblies. One of the processes is the role host, the other is an IIS website which will actually serve requests. But as they share assemblies, combined with the automagical nature of the NServiceBus hosting model, this would result in 2 processes with identical messagehandlers and configuration, not what you want.

Therefore we only support the hosting model for the role hosts (represented by webrole.cs in a webrole project). For the IIS website you have to configure the bus manually, using the Configure class and it’s extension methods.

Configuring a role manually has also been shown a lot in previous posts, but for completion sake I’ll show it again.

Configure.WithWeb() // With allows you to control the assemblies to load
    .Log4Net()
    .DefaultBuilder()
    .AzureConfigurationSource()
    .AzureMessageQueue()
            .JsonSerializer()
    .AzureSubcriptionStorage()
    .UnicastBus()
            .LoadMessageHandlers()
            .IsTransactional(true)
    .CreateBus()
    .Start();

Web workers

Now that you know that you can control the behavior of NServiceBus in both processes, you can create what we call ‘web workers’ in azure lingo. This are Windows Azure instances that host both webroles and worker roles. These are very interesting from a cost saving perspective, you can in fact host multiple website and workers when combining webworkers with NServiceBus’ dynamic azure host.

To set this up, you need to add a webrole.cs file to your webrole project in which you inherit from NServiceBus’ RoleEntryPoint and configure the endpoint AsA_Host. This will setup the role host to spin off child processes that act as workers, see my previous post on the details of how to do this. The host itself will not run a bus to avoid loading the website’s messagehandlers in it’s process space as these processes do share assemblies. (Remember! Selecting another role, like AsA_Worker, will load the messagehandlers)

In global.asax you can then configure the bus manually to be hosted in the website using the Configure class as stated above. All message handlers referenced from the webrole will be hosted in the IIS process and, as manual configuration ignores any IConfigureThisEndpoint implementation, you also avoid running a second dynamic host.

IIS 7.5

One small caveat when running in IIS version 7.5, which is installed on the latest azure OS families based on Windows Server 2008 R2, is that you cannot access either RoleEnvironment nor HttpContext early in the request lifecycle. Trying to configure NServiceBus at Application_Start will result in an exception as it does use these constructs internally.

An easy way to resolve this is to use .Net’s Lazy<T> to postpone initialization of the bus to the first Application_BeginRequest occurance in a thread safe manner:

private static readonly Lazy StartBus = new Lazy(ConfigureNServiceBus);

private static IBus ConfigureNServiceBus()
{
   var bus = Configure.WithWeb()
                  ...;

   return bus;
}

protected void Application_BeginRequest()
{
   Bus = StartBus.Value;
}

Want to get started with your own webworker?

Then check out the AzureHost sample in the NServiceBus trunk and build from there.

Happy coding!

About these ads

4 Responses to Hosting options for NServiceBus on Azure – Web roles & web workers

  1. Hi Yves,

    Just to let you know the NSB 3.3 Azure dlls won’t work with Azure SDK 1.8 (October tools).

    Regards, Alexey

    • Hi Alexey,

      I have not fully upgraded yet indeed, only the servicebus sdk has been upgraded so far. Main reason is that impact of storage client 2.0 may be huge, as there are a lot of breaking changes, and currently I don’t have much time to spend on it…

      Is this the issue you’re seeing, or is it something else?

      • Yves, I posted more detailed message to the NSB yahoo group. Basically even after upgrading references to 1.8.0.0 and building NSB Azure, I got my worker starting however it fails with an exception of the storage client. I found some posts saying that the October SDK emulator doesn’t work with 1.7 StorageClient dll or earlier. I checked the 2.0.0.0 version too and also found that it is significantly different. So I think for me the only option now is to downgrade my Cloud solution back to June SDK.

      • Ok, let’s continue the discussion there than.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: