A cloud service in Windows Azure will typically have
multiple concurrent instances. Each instance may be running all or a
part of the service’s codebase. As a developer, you control the number
and type of roles that you want running your service.
Web Roles and Worker Roles
Windows
Azure roles are comparable to standard Visual Studio projects, where
each instance represents a separate project. These roles represent
different types of applications that are natively supported by Windows
Azure. There are two types of roles that you can use to host services
with Windows Azure:
Web roles provide support
for HTTP and HTTPS through public endpoints and are hosted in IIS. They
are most comparable to regular ASP.NET projects, except for differences
in their configuration files and the assemblies they reference.
Worker roles can also
expose external, publicly facing TCP/IP endpoints on ports other than 80
(HTTP) and 443 (HTTPS); however, worker roles do not run in IIS. Worker
roles are applications comparable to Windows services and are suitable
for background processing.
Virtual Machines
Underneath the Windows Azure
platform, in an area that you and your service logic have no control
over, each role is given its own virtual machine or VM. Each VM is
created when you deploy your service or service-oriented solution to the
cloud. All of these VMs are managed by a modified hypervisor and hosted
in one of Microsoft’s global data centers.
Each VM can vary in size,
which pertains to the number of CPU cores and memory. This is something
that you control. So far, four pre-defined VM sizes are provided:
small – 1.7ghz single core, 2GB memory
medium – 2x 1.7ghz cores, 4GB memory
large – 4x 1.7ghz cores, 8GB memory
extra large – 8x 1.7ghz cores, 16GB memory
Notice how each subsequent VM
on this list is twice as big as the previous one. This simplifies VM
allocation, creation, and management by the hypervisor.
Windows Azure abstracts away
the management and maintenance tasks that come along with traditional
on-premise service implementations. When you deploy your service into
Windows Azure and the service’s roles are spun up, copies of those roles
are replicated
automatically to handle failover (for example, if a VM were to crash
because of hard drive failure). When a failure occurs, Windows Azure
automatically replaces that “unreliable” role with one of the “shadow”
roles that it originally created for your service.
This type of
failover is nothing new. On-premise service implementations have been
leveraging it for some time using clustering and disaster recovery
solutions. However, a common problem with these failover mechanisms is
that they are often server-focused. This means that the entire server is
failed over, not just a given service or service composition.
When you have multiple
services hosted on a Web server that crashes, each hosted service
experiences downtime between the current server crashing and the time it
takes to bring up the backup server. Although this may not affect
larger organizations with sophisticated infrastructure too much, it can
impact smaller IT enterprises that may not have the capital to invest in
setting up the proper type of failover infrastructure.
Also, suppose you discover
in hindsight after performing the failover that it was some background
worker process that caused the crash. This probably means that unless
you can address it quick enough, your failover server is under the same
threat of crashing.
Windows Azure addresses this
issue by focusing on application and hosting roles. Each service or
solution can have a Web frontend that runs in a Web role. Even though
each role has its own “active” virtual machine (assuming we are working
with single instances), Windows Azure creates copies of each role that
are physically located on one or more servers. These servers may or may
not be running in the same data center. These shadow VMs remain idle
until they are needed.
Should the background
process code crash the worker role and subsequently put the underlying
virtual machine out of commission, Windows Azure detects this and
automatically brings in one of the shadow worker roles. The faulty role
is essentially discarded. If the worker role breaks again, then Windows
Azure replaces it once more. All of this is happening without any
downtime to the solution’s Web role front end, or to any other services
that may be running in the cloud.
Input Endpoints
Web roles used to be the only
roles that could receive Internet traffic, but now worker roles can
listen to any port specified in the service definition file. Internet
traffic is received through the use of input endpoints. Input endpoints and their listening ports are declared in the service definition (*.csdef) file.
Keep
in mind that when you specify the port for your worker role to listen
on, Windows Azure isn’t actually going to assign that port to the
worker. In reality, the load balancer will open two ports—one for the
Internet and the other for your worker role. Suppose you wanted to
create an FTP worker role and in your service definition file you
specify port 21. This tells the fabric load balancer to open port 21 on
the Internet side, open pseudo-random port 33476 on the LAN side, and
begin routing FTP traffic to the FTP worker role.
In order to find out which port to initialize for the randomly assigned internal port, use the RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["FtpIn"].IPEndpoint object.
Inter-Role Communication
Inter-Role Communication (IRC)
allows multiple roles to talk to each other by exposing internal
endpoints. With an internal endpoint, you specify a name instead of a
port number. The Windows Azure application fabric will assign a port for
you automatically and will also manage the name-to-port mapping.
Here is an example of how you would specify an internal endpoint for IRC:
Example 1.
<ServiceDefinition xmlns= "http://schemas.microsoft.com/ServiceHosting/2008/10/ ServiceDefinition" name="HelloWorld"> <WorkerRole name="WorkerRole1"> <Endpoints> <InternalEndpoint name="NotifyWorker" protocol="tcp" /> </Endpoints> </WorkerRole> </ServiceDefinition>
|
In this example, NotifyWorker is the name of the internal endpoint of a worker role named WorkerRole1. Next, you need to define the internal endpoint, as follows:
Example 2.
RoleInstanceEndpoint internalEndPoint = RoleEnvironment.CurrentRoleInstance. InstanceEndpoints["NotificationService"]; this.serviceHost.AddServiceEndpoint( typeof(INameOfYourContract), binding, String.Format("net.tcp://{0}/NotifyWorker", internalEndPoint.IPEndpoint)); WorkerRole.factory = new ChannelFactory<IClientNotification>(binding);
|
You
only need to specify the IP endpoint of the other worker role instances
in order to communicate with them. For example, you could get a list of
these endpoints with the following routine:
Example 3.
var current = RoleEnvironment.CurrentRoleInstance; var endPoints = current.Role.Instances .Where(instance => instance != current) .Select(instance => instance.InstanceEndpoints["NotifyWorker"]);
|
IRC only works for roles in a
single application deployment. Therefore, if you have multiple
applications deployed and would like to enable some type of
cross-application role communication, IRC won’t work. You will need to
use queues instead.