This is the second article in our "Bring the clouds together: Azure + Bing Maps" series. You can find a preview of live demonstration on http://sqlazurebingmap.cloudapp.net/. For a list of articles in the series, please refer to http://blogs.msdn.com/b/windows-azure-support/archive/2010/08/11/bring-the-clouds-together-azure-bing-maps.aspx.
The architecture of an application depends heavily on user requirements, including functional requirements and non-functional requirements. Functional requirements are often defined as user stories. Some high level functional requirements of the "Plan My Travel" application are:
Some high level non-functional requirements of the "Plan My Travel" application are:
With the user requirements in mind, we can start to choose the platform for our application. There're a lot of platforms, which basically fall into 4 categories:
On-premises solutions are usually used for business solutions that are used by the organization internally. Since our application is consumer oriented, on-premises is out of question.
Our non-functional requirements indicate the scalability of our application is very important. A shared hosting solution should be enough during non-holiday seasons, but during holiday seasons, customers may continiously experience service outage due to the high demand. On the other hand, a cloud based solution, such as Windows Azure, allows us to scale the application dynamically, which is what we need. Unfortunately, we do not have a private data center yet, and the 3 servers IT provides us are obviously not enough for holiday seasons, even if we leverage virtualization and automation technologies such as Hyper-V and System Center. So that leaves us the only choice: the public cloud.
There're several public cloud offerings. Since our develop team is highly comfortable with .NET and Visual Studio, we want to choose a cloud vendor that supports the .NET Framework. In addition, none of the user requirements point out this application depends a particular infrastructure (such as OS, network, etc.). So we'd rather focus on the application only, and leave the infrastructure management tasks to the cloud vendor. This leads us to choose Windows Azure, a Platform-as-a-Service offer.
With Windows Azure, we create 2 instances of the application during non-holiday seasons. This allows us to handle at least 1,000 concurrent users without any service interuption. During holiday seasons, we will increase the instance number. As for how many instances do we need, the data will be collected during the first holiday season using performance monitoring features such as performance counter. After all, it is only a matter of modifying configuration file to change the instance number, so we don't need to worry too much about the scaling plan at the moment.
Windows Azure also supports almost every .NET features, which meets our developers' requirement. In addition, Windows Azure allows us to focus on the application itself, rather than infrastructures like OS and network. This saves our IT department a lot of management work. It also saves us a lot of cost in hardware maintaining, power usage, and air cooling.
Now that the platform is decided, we can create a high level architecture about how many components do we need, and which technology to choose for each component. Once again, we should read the user requirements.
First the component targeting end users: the client. After all, even if we're building a cloud solution, it is the client that end users really care.
A traveller should be able to access the application whereever possible. When travelling, the user often brings his phone, but not his laptop. But when planning the travel at home, most users prefer their powerful PC to their phone. So the application should be diliverd to the user's phone, as well as PC/laptop. That means we should either create a client that works accross all the devices, or create multiple clients for different scenarios.
A HTML client works nicely accross the devices. However, considering the fact that the screen size of mobile devices are often much smaller than PC, we will still end up with two versions, even if they use the same code base. In addtion, while a hardware accelerated browser (like IE9) + HTML 5 delivers a nice user experience that is almost on par with today's RIA technologies (such as Silverlight and Flash), most mobile browsers will not support HTML 5 in the near future, and it takes a lot of work to create a nice user expierence for a HTML client even with HTML 5 due to lacking of design tools like Expression Blend and Adobe Flash Professional. So in the end, we choose to create multiple clients: A HTML 4 client that dilivers the normal user expirence, powered by jQuery and AJAX. A Silverlight client for PC that dilivers better user expirence if the user has Silverlight installed. And a Windows Phone client for Windows Phone users. Third party developers can also create their own client for more devices.
By choosing HTML and Silverlight, we're effectively distributing applications from the cloud. Those applications run on the user machine. But users simply navigate to our cloud site, and the applications are seemlessly downloaded to the client.
Now move on to the service. Since we need to support both our own clients and third party clients, we have to create a service API based on open standards. We found WCF Data Services very attractive, as it allows us to create REST services that supports multiple common formats (such as XML and JSON) without too much effort, using an open protocol: The OData.
As for data storage, in the Windows Azure platform, we have 2 choices: table storage and SQL Azure. Table storage offers dynamic schema and built-in horizontal partitioning capbility, but it lacks a lot of features such as orderby and limited data types. Our application doesn't need dynamic schema (at least in V1). The built-in horizontal partitioning capbility is very attractive, since it allows us to query from hundereds of TB data with high performance (as long as you choose the proper partition strategy). But this is not an immediate requirement. So we choose SQL Azure for the data storage used in the first version of our product. In the future, if we want to switch to table storage or an external storage service (such as Amazon S3), it should not affect our clients at all, as long as our service contract doesn't change. This is the major benifit of SOA.
SQL Azure allows us to store both relational data and spatial data. Most of our data can be stored as relational data, but since we need to calculate the distance between two places, spatial data will be a great help. So we decide to use spatial data to store the location information, and use relational data to store other information.
When accessing relational data, an O/R mapping framework is a great help. Since we're using .NET, we choose ADO.NET Entity Framework. Even though Entity Framework doesn't support spatial data yet, it will sure ease our data accessing code.
Finally, we also need a map! We can build our own simple map, but why not leverage a free map service like Bing Maps? The Bing Maps REST API should work fine with our client applications, which access our own service using REST API. It also provides both an AJAX control and a Silverlight control, which can be used in all clients we support.
This article discussed how to make decition when architecting for a typical cloud based consumer oriented application. The next article discusses how to design a scalable cloud database.