title | description | services | documentationcenter | author | manager | editor | ms.assetid | ms.service | ms.workload | ms.tgt_pltfrm | ms.devlang | ms.topic | ms.date | ms.author |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
.NET multi-tier application using Azure Service Bus | Microsoft Docs |
A .NET tutorial that helps you develop a multi-tier app in Azure that uses Service Bus queues to communicate between tiers. |
service-bus-messaging |
.net |
sethmanheim |
timlt |
1b8608ca-aa5a-4700-b400-54d65b02615c |
service-bus-messaging |
tbd |
na |
dotnet |
get-started-article |
10/16/2017 |
sethm |
Developing for Microsoft Azure is easy using Visual Studio and the free Azure SDK for .NET. This tutorial walks you through the steps to create an application that uses multiple Azure resources running in your local environment.
You will learn the following:
- How to enable your computer for Azure development with a single download and install.
- How to use Visual Studio to develop for Azure.
- How to create a multi-tier application in Azure using web and worker roles.
- How to communicate between tiers using Service Bus queues.
[!INCLUDE create-account-note]
In this tutorial you'll build and run the multi-tier application in an Azure cloud service. The front end is an ASP.NET MVC web role and the back end is a worker-role that uses a Service Bus queue. You can create the same multi-tier application with the front end as a web project, that is deployed to an Azure website instead of a cloud service. You can also try out the .NET on-premises/cloud hybrid application tutorial.
The following screen shot shows the completed application.
To submit an order for processing, the front-end UI component, running in the web role, must interact with the middle tier logic running in the worker role. This example uses Service Bus messaging for the communication between the tiers.
Using Service Bus messaging between the web and middle tiers decouples the two components. In contrast to direct messaging (that is, TCP or HTTP), the web tier does not connect to the middle tier directly; instead it pushes units of work, as messages, into Service Bus, which reliably retains them until the middle tier is ready to consume and process them.
Service Bus provides two entities to support brokered messaging: queues and topics. With queues, each message sent to the queue is consumed by a single receiver. Topics support the publish/subscribe pattern in which each published message is made available to a subscription registered with the topic. Each subscription logically maintains its own queue of messages. Subscriptions can also be configured with filter rules that restrict the set of messages passed to the subscription queue to those that match the filter. The following example uses Service Bus queues.
This communication mechanism has several advantages over direct messaging:
-
Temporal decoupling. With the asynchronous messaging pattern, producers and consumers need not be online at the same time. Service Bus reliably stores messages until the consuming party is ready to receive them. This enables the components of the distributed application to be disconnected, either voluntarily, for example, for maintenance, or due to a component crash, without impacting the system as a whole. Furthermore, the consuming application might only need to come online during certain times of the day.
-
Load leveling. In many applications, system load varies over time, while the processing time required for each unit of work is typically constant. Intermediating message producers and consumers with a queue means that the consuming application (the worker) only needs to be provisioned to accommodate average load rather than peak load. The depth of the queue grows and contracts as the incoming load varies. This directly saves money in terms of the amount of infrastructure required to service the application load.
-
Load balancing. As load increases, more worker processes can be added to read from the queue. Each message is processed by only one of the worker processes. Furthermore, this pull-based load balancing enables optimal use of the worker machines even if the worker machines differ in terms of processing power, as they will pull messages at their own maximum rate. This pattern is often termed the competing consumer pattern.
The following sections discuss the code that implements this architecture.
Before you can begin developing Azure applications, get the tools and set up your development environment.
- Install the Azure SDK for .NET from the SDK downloads page.
- In the .NET column, click the version of Visual Studio you are using. The steps in this tutorial use Visual Studio 2015, but they also work with Visual Studio 2017.
- When prompted to run or save the installer, click Run.
- In the Web Platform Installer, click Install and proceed with the installation.
- Once the installation is complete, you will have everything necessary to start to develop the app. The SDK includes tools that let you easily develop Azure applications in Visual Studio.
The next step is to create a namespace, and obtain a Shared Access Signature (SAS) key for that namespace. A namespace provides an application boundary for each application exposed through Service Bus. A SAS key is generated by the system when a namespace is created. The combination of namespace name and SAS key provides the credentials for Service Bus to authenticate access to an application.
[!INCLUDE service-bus-create-namespace-portal]
In this section, you build the front end of your application. First, you create the pages that your application displays. After that, add code that submits items to a Service Bus queue and displays status information about the queue.
-
Using administrator privileges, start Visual Studio: right-click the Visual Studio program icon, and then click Run as administrator. The Azure compute emulator, discussed later in this article, requires that Visual Studio be started with administrator privileges.
In Visual Studio, on the File menu, click New, and then click Project.
-
From Installed Templates, under Visual C#, click Cloud and then click Azure Cloud Service. Name the project MultiTierApp. Then click OK.
-
From the Roles pane, double-click ASP.NET Web Role.
-
Hover over WebRole1 under Azure Cloud Service solution, click the pencil icon, and rename the web role to FrontendWebRole. Then click OK. (Make sure you enter "Frontend" with a lower-case 'e,' not "FrontEnd".)
-
From the New ASP.NET Project dialog box, in the Select a template list, click MVC.
-
Still in the New ASP.NET Project dialog box, click the Change Authentication button. In the Change Authentication dialog box, ensure that No Authentication is selected, and then click OK. For this tutorial, you're deploying an app that doesn't need a user login.
-
Back in the New ASP.NET Project dialog box, click OK to create the project.
-
In Solution Explorer, in the FrontendWebRole project, right-click References, then click Manage NuGet Packages.
-
Click the Browse tab, then search for WindowsAzure.ServiceBus. Select the WindowsAzure.ServiceBus package, click Install, and accept the terms of use.
Note that the required client assemblies are now referenced and some new code files have been added.
-
In Solution Explorer, right-click Models and click Add, then click Class. In the Name box, type the name OnlineOrder.cs. Then click Add.
In this section, you create the various pages that your application displays.
-
In the OnlineOrder.cs file in Visual Studio, replace the existing namespace definition with the following code:
namespace FrontendWebRole.Models { public class OnlineOrder { public string Customer { get; set; } public string Product { get; set; } } }
-
In Solution Explorer, double-click Controllers\HomeController.cs. Add the following using statements at the top of the file to include the namespaces for the model you just created, as well as Service Bus.
using FrontendWebRole.Models; using Microsoft.ServiceBus.Messaging; using Microsoft.ServiceBus;
-
Also in the HomeController.cs file in Visual Studio, replace the existing namespace definition with the following code. This code contains methods for handling the submission of items to the queue.
namespace FrontendWebRole.Controllers { public class HomeController : Controller { public ActionResult Index() { // Simply redirect to Submit, since Submit will serve as the // front page of this application. return RedirectToAction("Submit"); } public ActionResult About() { return View(); } // GET: /Home/Submit. // Controller method for a view you will create for the submission // form. public ActionResult Submit() { // Will put code for displaying queue message count here. return View(); } // POST: /Home/Submit. // Controller method for handling submissions from the submission // form. [HttpPost] // Attribute to help prevent cross-site scripting attacks and // cross-site request forgery. [ValidateAntiForgeryToken] public ActionResult Submit(OnlineOrder order) { if (ModelState.IsValid) { // Will put code for submitting to queue here. return RedirectToAction("Submit"); } else { return View(order); } } } }
-
From the Build menu, click Build Solution to test the accuracy of your work so far.
-
Now, create the view for the
Submit()
method you created earlier. Right-click within theSubmit()
method (the overload ofSubmit()
that takes no parameters), and then choose Add View. -
A dialog box appears for creating the view. In the Template list, choose Create. In the Model class list, select the OnlineOrder class.
-
Click Add.
-
Now, change the displayed name of your application. In Solution Explorer, double-click the Views\Shared\_Layout.cshtml file to open it in the Visual Studio editor.
-
Replace all occurrences of My ASP.NET Application with Northwind Traders Products.
-
Remove the Home, About, and Contact links. Delete the highlighted code:
-
Finally, modify the submission page to include some information about the queue. In Solution Explorer, double-click the Views\Home\Submit.cshtml file to open it in the Visual Studio editor. Add the following line after
<h2>Submit</h2>
. For now, theViewBag.MessageCount
is empty. You will populate it later.<p>Current number of orders in queue waiting to be processed: @ViewBag.MessageCount</p>
-
You now have implemented your UI. You can press F5 to run your application and confirm that it looks as expected.
Now, add code for submitting items to a queue. First, you create a class that contains your Service Bus queue connection information. Then, initialize your connection from Global.aspx.cs. Finally, update the submission code you created earlier in HomeController.cs to actually submit items to a Service Bus queue.
-
In Solution Explorer, right-click FrontendWebRole (right-click the project, not the role). Click Add, and then click Class.
-
Name the class QueueConnector.cs. Click Add to create the class.
-
Now, add code that encapsulates the connection information and initializes the connection to a Service Bus queue. Replace the entire contents of QueueConnector.cs with the following code, and enter values for
your Service Bus namespace
(your namespace name) andyourKey
, which is the primary key you previously obtained from the Azure portal.using System; using System.Collections.Generic; using System.Linq; using System.Web; using Microsoft.ServiceBus.Messaging; using Microsoft.ServiceBus; namespace FrontendWebRole { public static class QueueConnector { // Thread-safe. Recommended that you cache rather than recreating it // on every request. public static QueueClient OrdersQueueClient; // Obtain these values from the portal. public const string Namespace = "your Service Bus namespace"; // The name of your queue. public const string QueueName = "OrdersQueue"; public static NamespaceManager CreateNamespaceManager() { // Create the namespace manager which gives you access to // management operations. var uri = ServiceBusEnvironment.CreateServiceUri( "sb", Namespace, String.Empty); var tP = TokenProvider.CreateSharedAccessSignatureTokenProvider( "RootManageSharedAccessKey", "yourKey"); return new NamespaceManager(uri, tP); } public static void Initialize() { // Using Http to be friendly with outbound firewalls. ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.Http; // Create the namespace manager which gives you access to // management operations. var namespaceManager = CreateNamespaceManager(); // Create the queue if it does not exist already. if (!namespaceManager.QueueExists(QueueName)) { namespaceManager.CreateQueue(QueueName); } // Get a client to the queue. var messagingFactory = MessagingFactory.Create( namespaceManager.Address, namespaceManager.Settings.TokenProvider); OrdersQueueClient = messagingFactory.CreateQueueClient( "OrdersQueue"); } } }
-
Now, ensure that your Initialize method gets called. In Solution Explorer, double-click Global.asax\Global.asax.cs.
-
Add the following line of code at the end of the Application_Start method.
FrontendWebRole.QueueConnector.Initialize();
-
Finally, update the web code you created earlier, to submit items to the queue. In Solution Explorer, double-click Controllers\HomeController.cs.
-
Update the
Submit()
method (the overload that takes no parameters) as follows to get the message count for the queue.public ActionResult Submit() { // Get a NamespaceManager which allows you to perform management and // diagnostic operations on your Service Bus queues. var namespaceManager = QueueConnector.CreateNamespaceManager(); // Get the queue, and obtain the message count. var queue = namespaceManager.GetQueue(QueueConnector.QueueName); ViewBag.MessageCount = queue.MessageCount; return View(); }
-
Update the
Submit(OnlineOrder order)
method (the overload that takes one parameter) as follows to submit order information to the queue.public ActionResult Submit(OnlineOrder order) { if (ModelState.IsValid) { // Create a message from the order. var message = new BrokeredMessage(order); // Submit the order. QueueConnector.OrdersQueueClient.Send(message); return RedirectToAction("Submit"); } else { return View(order); } }
-
You can now run the application again. Each time you submit an order, the message count increases.
You will now create the worker role that processes the order submissions. This example uses the Worker Role with Service Bus Queue Visual Studio project template. You already obtained the required credentials from the portal.
-
Make sure you have connected Visual Studio to your Azure account.
-
In Visual Studio, in Solution Explorer right-click the Roles folder under the MultiTierApp project.
-
Click Add, and then click New Worker Role Project. The Add New Role Project dialog box appears.
-
In the Add New Role Project dialog box, click Worker Role with Service Bus Queue.
-
In the Name box, name the project OrderProcessingRole. Then click Add.
-
Copy the connection string that you obtained in step 9 of the "Create a Service Bus namespace" section to the clipboard.
-
In Solution Explorer, right-click the OrderProcessingRole you created in step 5 (make sure that you right-click OrderProcessingRole under Roles, and not the class). Then click Properties.
-
On the Settings tab of the Properties dialog box, click inside the Value box for Microsoft.ServiceBus.ConnectionString, and then paste the endpoint value you copied in step 6.
-
Create an OnlineOrder class to represent the orders as you process them from the queue. You can reuse a class you have already created. In Solution Explorer, right-click the OrderProcessingRole class (right-click the class icon, not the role). Click Add, then click Existing Item.
-
Browse to the subfolder for FrontendWebRole\Models, and then double-click OnlineOrder.cs to add it to this project.
-
In WorkerRole.cs, change the value of the QueueName variable from
"ProcessingQueue"
to"OrdersQueue"
as shown in the following code.// The name of your queue. const string QueueName = "OrdersQueue";
-
Add the following using statement at the top of the WorkerRole.cs file.
using FrontendWebRole.Models;
-
In the
Run()
function, inside theOnMessage()
call, replace the contents of thetry
clause with the following code.Trace.WriteLine("Processing", receivedMessage.SequenceNumber.ToString()); // View the message as an OnlineOrder. OnlineOrder order = receivedMessage.GetBody<OnlineOrder>(); Trace.WriteLine(order.Customer + ": " + order.Product, "ProcessingMessage"); receivedMessage.Complete();
-
You have completed the application. You can test the full application by right-clicking the MultiTierApp project in Solution Explorer, selecting Set as Startup Project, and then pressing F5. Note that the message count does not increment, because the worker role processes items from the queue and marks them as complete. You can see the trace output of your worker role by viewing the Azure Compute Emulator UI. You can do this by right-clicking the emulator icon in the notification area of your taskbar and selecting Show Compute Emulator UI.
To learn more about Service Bus, see the following resources:
To learn more about multi-tier scenarios, see: