Saturday, June 7, 2014

Microsoft 70-486: Design a distributed application

Exam Objectives


Design a hybrid application (on-premises versus off-premises, including Azure), plan for session management in a distributed environment, plan web farms, **integrate web services

Quick Overview of Training Materials


MSDN - ASP.NET Session State OverviewSession-State Modes
MSDN - Technet - About Server Farms, Server Affinity Page
Make an ASP.NET MVC application Web Farm Ready
Out-of-Process Caching in ASP.NET
MSDN - Differences between On-Premises AppFabric 1.1 Caching and Azure Managed Cache Service


Integrate web services


This objective isn't included in the exam guide from Microsoft, but it is included in the Exam Ref book, so I thought it would be a good idea to cover it here. The exam ref does make a good point about this objective, however: if you are going to have different parts of your application spread over multiple pieces of hardware, or even in different datacenters, then they are going to need a way to talk to each other.  One way to accomplish this is to create a service layer that serves up data from the data layer using web services.

It is not an all or nothing deal with web services, it is possible for them to live side by side with MVC in the same project.  The Web API controller is accessed by default using the /api/{controller}/{action}/{id} url pattern, which is identical to the default MVC routing except it includes the "/api" at the start.  In addition to Web API, which is lightweight and easy to use, it is also possible to create web services using Windows Communication Foundation (WCF).  However, WCF is not part of ASP.NET, so while they can work together, it isn't as simple as adding a new controller to your MVC application. That is not to say that adding a web service to an MVC project is hard (right click on "References" and select "Add service reference..."), it just has to live in a separate project.

Adding Web API controllers to an MVC project is one Ctrl+Shift+A away. Notice there is no WCF option...

The Web API Study and Web API Design documents have a lot of good information on the why and how behind implementing web services.  One of the leading technical drivers behind adopting a web API architecture is application integration. The design guide includes best practices for making the API easy for developers to adopt and program against, and discusses (at a high level) how the API facade pattern can facilitate exposing disparate systems with a common API.

Chapter 7 in the O'Reilly text covers Web API, not super in depth but probably well enough for the purposes of this exam (70-487 covers Web API in depth...).  Web API controllers are nearly identical to MVC controllers.  Routing is slightly different, as it is registered with .MapHttpRoute instead of .MapRoute. Convention over Configuration works pretty much the same way with API controllers, and you must be mindful that you don't have naming conflicts between the two.  By default, Action methods named after standard HTTP verbs (GET, POST, PUT, DELETE) will not require annotation such as [HttpPost], they are picked up by convention. Other actions, if you define them, will need the annotations. One apparent difference with Web API is the need for a dependency resolver to implement the repository pattern for data access. Exception filters can be used to catch unhandled exceptions from the API. These filters are much like MVC filters, they just live in a different namespace and behave a bit different, and it is worth noting that they do not handle each other's errors. Finally, Web Api controllers can handle many different MIME types, depending on how they are configured.

Our Hackathon project used Web API,  XML was returned by default...
... but changing the "Accept" request header to "application/json" gets us Json. Handy, and the Json response was about a third the size (900B vs 2500B)!

Design a hybrid application


According to the exam ref, a hybrid application is one that is located in multiple locations, and uses the example of an application with both on-premise and Azure components.  The book identifies two patterns for hybrid applications: client-centric and system-centric. Other than noting that they are more prone to failure the book doesn't elaborate much on the client-centric patter.  It does, however, mention that systen-centric hybrid applications use a service bus to distribute requests, and includes a link to an MSDN tutorial on implementing a simple hybrid on-premise/Azure application.  Working through the tutorial is a useful exercise, I've shared my resulting code on Github: https://github.com/sabotuer99/AzureServiceBusDemo.

This is the end result with the Service Bus Demo tutorial

Some of the concerns to consider when planning a hybrid application:

  • Connections are not as reliable compared to an application that is located completely in one place
  • Authorization will need to be managed across multiple domains
  • Security of sensitive data is complicated when it is needed by a cloud based component.

Plan for session management in distributed environment


Before one can answer the question of HOW to manage state with sessions, it should first be ascertained to what degree the application is going to maintain state at all.  Whereas Web Forms tried to emulate desktop application statefulness by using the View State, MVC is geared more toward the inherently stateless nature of the web.  Rather than serializing everything into the View State, MVC aims to include relevant variables with every request, either as part of the route, in the query string, or in the request headers.

For occasions when it is necessary to maintain state, there are several options with MVC.  Hidden inputs, query string values, and cookies can all be used on the client side, and Application State, Session State, and Profiles can all be used on the server side. Using Session state in a distributed environment presents a unique challenge, because by default Session state is set to operate in InProc mode, which effectively limits the scope of the data to the individual web server.  To make InProc mode work in a distributed environment, it is necessary to create affinity between the client and the server, so that every request goes to the same server for the duration of the session.

The alternative to setting up affinity is to share session data across all the web servers.  There are two options that allow session data be shared by multiple machines: state server mode and sql server mode.

State server mode requires that the ASP.NET state service is running on the server being used to store the state information. Furthermore, the configuration section of the application's web.config file must include an entry setting the sessionState mode to "StateServer" and including the connection string to the state server, like so:

<configuration>
  <system.web>
    <sessionState mode="StateServer"
      stateConnectionString="tcpip=SampleStateServer:42424"
      cookieless="false"
      timeout="20"/>
  </system.web>
</configuration>

Sqlserver mode is similar, only instead of using a state server, the session information is persisted in a SQL database.  As such, this mode requires setting up a SQL session state database and adding the appropriate values to the web.config file:

<configuration>
  <system.web>
    <sessionState mode="SQLServer"
      sqlConnectionString="Integrated Security=SSPI;data 
        source=SampleSqlServer;" />
  </system.web>
</configuration>

Plan web farms


Using multiple application servers has the benefit of increased up time and the ability to scale as an application sees more requests, but it does require some measures be taken to ensure the application will behave as expected in such an environment.  Maintaining session state across multiple machines was discussed above: using one of the OutProc session modes will enable sessions across the webfarm.  Caching in a distributed environment presents similar challenges.

The ASP.NET Cache object behaves similar to the InProc session: it only stores information on the local server, so requests to other machines for the same resource will not have access to those cached items.  Unlike session state, there is not a simple built in option in IIS to enable shared cache resources. Instead, some form of middleware is necessary to provide a distributed cache service.  Microsoft AppFabric includes this functionality, as do other commercial and open source products.

Implementing AppFabric involves first installing AppFabric, then adding the appropriate entries to the web.config file in the project and adding references to the Microsoft.ApplicationServer.Caching.Core and Microsoft.ApplicationServer.Caching.Client assemblies. Once set up, using the cache in your application is as simple as calling the DataCacheFactory() method.

Azure also offers cloud based caching services based on either Redis or AppFabric (Managed Cache Service and In-Role Cache).  Most of the features of Azure Managed Cache Service are the same as AppFabric 1.1.

6 comments:

  1. You've explained the concepts from this objective so much better than William Penberthy, the author of the Exam Ref book. Thank you and well done!

    ReplyDelete
  2. Your article is awesome. Thank you!

    ReplyDelete
  3. OMG I am so glad I found this blog; great info here as I struggle to pass the 70-486 exam.

    ReplyDelete
    Replies
    1. Thanks for the feedback Lorrie, hope it helps you learn and pass the cert test =)

      Delete