Windows® Azure is a cloud services operating system that serves as the development, service hosting and service management environment for the Azure Services Platform. Windows Azure provides developers with on-demand compute and storage to host, scale, and manage Web applications on the Internet through Microsoft® data centers.
A service hosted in the Windows Azure fabric implements one or more roles. A role is a scalable component built with managed code. A service may run multiple instances of a role. Within the Windows Azure fabric, running instances of a role are replicated across multiple physical machines to implement all or part of the functionality of a service. Each role runs in a virtual machine that has following predictable resources allocation: 64bit Windows Server 2008 OS, 1.5-1.7 64 bit CPU, 1.7 GB RAM memory, 100 MB/s network and 250 GB storage space (only 50 available in the CTP). So basically the developer creates the application as being used by one user and, in the cloud, many instances of it are created to support multiple clients.
The Windows Azure fabric currently supports two types of roles:
- Web Role is an application accessible through HTTP and/or HTTPS endpoints. A web role is hosted in an environment designed to support a subset of ASP.NET and Windows Communication Foundation technologies.
- A Worker Role is a background processing application. A worker role may communicate with storage services and with other Internet-based services. It does not expose any external endpoints. A worker role can read requests from a queue defined in the Queue storage service.
Because workers do not have some public endpoints some architectural considerations must be taken. How can a worker process external data? How web roles and workers exchange information? Why do we need workers?
Web roles can send/receive data to/from workers using the Storage Services. Storage Services include Blob, Queues and Tables.
- Blobs are sets of binary data; they are similar with files from your local windows storage. Blobs are organized in catalogs that are similar to folders.
- Queues are just message queues. They are FIFO (First In First Out) data structures that can hold messages up to 8kb each.
- Tables provide structured storage in the form of tables. However this is not a relational database system! They are just some tables that hold data with no relation between them.
Of course, web role or worker role can make any external HTTP/HTTPS request. Also blobs, queues and tables can be accessed from outside the cloud through HTTP(S) requests. I will focus today on the internal could application architecture and not on the outside requests.
While you service is running in the cloud you cannot know where a specific instance is located, instances do not communicate directly one with another and you don't have references to them. Every instance is "blind". It knows only about itself. Also HTTP requests cannot be directed to a specific instance – the fabric has a load balancer that redirects requests. The same thing applies to workers: jobs cannot be dispatched to a specific worker.
The best strategy in this distributed environment is similar to the thread pool pattern. Web roles get requests from users, put messages in a queue and, asynchronously, a worker will take one message and process it. Even though instances can be located anywhere on the Globe, a message from the queue will be taken by only one worker – pretty cool, huh?
If the information that needs to be send to the worker is larger than 8KB then part of it can be saved in blobs or tables. For example you could use the table to store information about the client (name, address, phone etc) who sent the request, save in the blob the documents he sent and put a message in a queue saying "There is a new request. It was stored, in a table, having ID number 1234 and its associated blobs are Document1, Document2 and Document3". The worker who will pop the message must first get the information from table, documents from blob containers, process them and save the results.
Workers act like a team that has a number of tasks to complete. When someone from the team finishes a task it takes another one. If there are no more tasks it waits.
Because Azure pricing will be influenced by the number of instances it is said that this value will be able to be modified "on the fly". Assuming that your business has 1 million requests in December and only 10.000 in January then you could use 1000 web role instances in Dec. and only 10 in Jan, dynamically scaling your investments. Making roles and instances independent and communicating between them using the Storage Services gives you the ability to scale up or down the application transparently.
Another thing that must be taken in consideration when building could services is their asynchronously nature. If no worker is available to process a job, the message might be placed in a queue and processed later (maybe after 5 seconds or 5 hours). So client interfaces must support later result retrieving and must inform the user that the response might be delayed.