PageRenderTime 387ms CodeModel.GetById 83ms app.highlight 186ms RepoModel.GetById 19ms app.codeStats 0ms

/articles/cloud-services-dotnet-multi-tier-app-using-service-bus-queues.md

https://github.com/Auguronomics/azure-content
Markdown | 662 lines | 474 code | 188 blank | 0 comment | 0 complexity | b45f1cbe963d196e872f62b600084ded MD5 | raw file
  1<properties linkid="dev-net-e2e-multi-tier" urlDisplayName="Multi-Tier Application" pageTitle=".NET Multi-Tier Application - Windows Azure Tutorial" metaKeywords="Azure Service Bus queue tutorial, Azure queue tutorial, Azure worker role tutorial, Azure .NET queue tutorial, Azure C# queue tutorial, Azure C# worker role tutorial" description="A tutorial that helps you develop a multi-tier app in Windows Azure that uses Service Bus queues to communicate between tiers. Samples in .NET." metaCanonical="" services="cloud-services,service-bus" documentationCenter=".NET" title=".NET Multi-Tier Application Using Service Bus Queues" authors=""  solutions="" writer="sethm" manager="dwrede" editor="mattshel"  />
  2
  3
  4
  5
  6
  7# .NET Multi-Tier Application Using Service Bus Queues
  8
  9Developing for Windows Azure is easy using Visual Studio 2012 and the
 10free Windows Azure SDK for .NET. If you do not already have Visual
 11Studio 2012, the SDK will automatically install Visual Studio Express 2012 for Web, so you can start developing for Windows Azure entirely for
 12free. This guide assumes you have no prior experience using Windows
 13Azure. On completing this guide, you will have an application that uses
 14multiple Windows Azure resources running in your local environment and
 15demonstrating how a multi-tier application works.
 16
 17You will learn:
 18
 19-   How to enable your computer for Windows Azure development with a
 20    single download and install.
 21-   How to use Visual Studio to develop for Windows Azure.
 22-   How to create a multi-tier application in Windows Azure using web
 23    and worker roles.
 24-   How to communicate between tiers using Service Bus Queues.
 25
 26In this tutorial you'll build and run the multi-tier application in a Windows Azure Cloud Service. The front end will be an ASP.NET MVC web role and the back end will be a worker-role. You could create the same multi-tier application with the front end as a web project that would be deployed to a Windows Azure Web Site instead of a cloud service. For instructions about what to do differently a Windows Azure Web Site front end, see the [Next steps](#nextsteps) section.
 27
 28A screenshot of the completed application is shown below:
 29
 30![][0]
 31
 32**Note** Windows Azure also provides storage queue functionality. For more information about Windows Azure storage queues and Service Bus queues, see [Windows Azure Queues and Windows Azure Service Bus Queues - Compared and Contrasted][sbqueuecomparison].  
 33
 34[WACOM.INCLUDE [create-account-note](../includes/create-account-note.md)]
 35
 36<h2><span class="short-header">Inter-role communication</span>Scenario overview: inter-role communication</h2>
 37
 38To submit an order for processing, the front end UI component, running
 39in the web role, needs to interact with the middle tier logic running in
 40the worker role. This example uses Service Bus brokered messaging for
 41the communication between the tiers.
 42
 43Using brokered messaging between the web and middle tiers decouples the
 44two components. In contrast to direct messaging (that is, TCP or HTTP),
 45the web tier does not connect to the middle tier directly; instead it
 46pushes units of work, as messages, into the Service Bus, which reliably
 47retains them until the middle tier is ready to consume and process them.
 48
 49The Service Bus provides two entities to support brokered messaging:
 50queues and topics. With queues, each message sent to the queue is
 51consumed by a single receiver. Topics support the publish/subscribe
 52pattern in which each published message is made available to each
 53subscription registered with the topic. Each subscription logically
 54maintains its own queue of messages. Subscriptions can also be
 55configured with filter rules that restrict the set of messages passed to
 56the subscription queue to those that match the filter. This example uses
 57Service Bus queues.
 58
 59![][1]
 60
 61This communication mechanism has several advantages over direct
 62messaging, namely:
 63
 64-   **Temporal decoupling.** With the asynchronous messaging pattern,
 65    producers and consumers need not be online at the same time. Service
 66    Bus reliably stores messages until the consuming party is ready to
 67    receive them. This allows the components of the distributed
 68    application to be disconnected, either voluntarily, for example, for
 69    maintenance, or due to a component crash, without impacting the
 70    system as a whole. Furthermore, the consuming application may only
 71    need to come online during certain times of the day.
 72
 73-   **Load leveling**. In many applications, system load varies over
 74    time whereas the processing time required for each unit of work is
 75    typically constant. Intermediating message producers and consumers
 76    with a queue means that the consuming application (the worker) only
 77    needs to be provisioned to accommodate average load rather than peak
 78    load. The depth of the queue will grow and contract as the incoming
 79    load varies. This directly saves money in terms of the amount of
 80    infrastructure required to service the application load.
 81
 82-   **Load balancing.** As load increases, more worker processes can be
 83    added to read from the queue. Each message is processed by only one
 84    of the worker processes. Furthermore, this pull-based load balancing
 85    allows for optimum utilization of the worker machines even if the
 86    worker machines differ in terms of processing power as they will
 87    pull messages at their own maximum rate. This pattern is often
 88    termed the competing consumer pattern.
 89
 90    ![][2]
 91
 92The following sections discuss the code that implements this
 93architecture.
 94
 95<h2><span class="short-header">Set up environment</span>Set up the development environment</h2>
 96
 97Before you can begin developing your Windows Azure application, you need
 98to get the tools and set-up your development environment.
 99
1001.  To install the Windows Azure SDK for .NET, click the button below:
101
102    [Get Tools and SDK][]
103
1042. 	Click **install the SDK**.
105
1063. 	Choose the link for the version of Visual Studio you are using. The steps in this tutorial use Visual Studio 2012:
107
108	![][32]
109
1104. 	When prompted to run or save the installation file, click
111    **Run**:
112
113    ![][3]
114
1155.  In the Web Platform Installer, click **Install** and proceed with the installation:
116
117    ![][33]
118
1196.  Once the installation is complete, you will have everything
120    necessary to start developing. The SDK includes tools that let you
121    easily develop Windows Azure applications in Visual Studio. If you
122    do not have Visual Studio installed, it also installs the free
123    Visual Studio Express for Web.
124
125<h2><span class="short-header">Set up the namespace</span>Set up the Service Bus namespace</h2>
126
127The next step is to create a service namespace, and to obtain a shared
128secret key. A service namespace provides an application boundary for
129each application exposed through Service Bus. A shared secret key is
130automatically generated by the system when a service namespace is
131created. The combination of service namespace and shared secret key
132provides a credential for Service Bus to authenticate access to an
133application.
134
1351.  Log into the [Windows Azure Management Portal][].
136
1372.  In the left navigation pane of the Management Portal, click
138    **Service Bus**.
139
1403.  In the lower pane of the Management Portal, click **Create**.
141
142    ![][6]
143
1444.  In the **Add a new namespace** dialog, enter a namespace name.
145    The system immediately checks to see if the name is available.   
146    ![][7]
147
1485.  After making sure the namespace name is available, choose the
149    country or region in which your namespace should be hosted (make
150    sure you use the same country/region in which you are deploying your
151    compute resources).
152
153    IMPORTANT: Pick the **same region** that you intend to choose for
154    deploying your application. This will give you the best performance.
155
1566.  Click the check mark. The system now creates your service
157    namespace and enables it. You might have to wait several minutes as
158    the system provisions resources for your account.
159
160	![][27]
161
1627.  In the main window, click the name of your service namespace.
163
164	![][30]
165
1668. Click **Connection Information**.
167
168	![][31]
169
1709.  In the **Access connection information** pane, find the **Default Issuer** and **Default Key** entries.
171
17210.  Make a note of the key, or copy it to the clipboard.
173
174<h2><span class="short-header">Create a web role</span>Create a web role</h2>
175
176In this section, you will build the front end of your application. You
177will first create the various pages that your application displays.
178After that, you will add the code for submitting items to a Service Bus
179Queue and displaying status information about the queue.
180
181### Create the project
182
1831.  Using administrator privileges, start either Microsoft Visual Studio
184    2012 or Microsoft Visual Studio Express for Web. To start Visual
185    Studio with administrator privileges, right-click **Microsoft Visual
186    Studio 2012 (or Microsoft Visual Studio Express for Web)** and
187    then click **Run as administrator**. The Windows Azure compute emulator,
188    discussed later in this guide, requires that Visual Studio be
189    launched with administrator privileges.
190
191    In Visual Studio, on the **File** menu, click **New**, and then
192    click **Project**.
193
194    ![][8]
195
1962.  From **Installed Templates**, under **Visual C#**, click Cloud and
197    then click **Windows Azure Project**. Name the project
198    **MultiTierApp**. Then click **OK**.
199
200    ![][9]
201
2023.  From **.NET Framework 4** roles, double-click **ASP.NET MVC 4 Web
203    Role**.
204
205    ![][10]
206
2074.  Hover over **MvcWebRole1** under **Windows Azure Cloud Service solution**, click
208    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".)
209
210    ![][11]
211
2125.  From the **Select a template** list, click **Internet Application**,
213    then click **OK**.
214
215    ![][12]
216
2176.  In **Solution Explorer**, right-click **References**, then click
218    **Manage NuGet Packages...** or **Add Library Package Reference**.
219
2207.  Select **Online** on the left-hand side of the dialog. Search for
221    "**WindowsAzure**" and select the **Windows Azure Service
222    Bus** item. Then complete the installation and close this dialog.
223
224    ![][13]
225
2268.  Note that the required client assemblies are now referenced and some
227    new code files have been added.
228
2299.  In **Solution Explorer**, right click **Models** and click **Add**,
230    then click **Class**. In the Name box, type the name
231    **OnlineOrder.cs**. Then click **Add**.
232
233### Write the code for your web role
234
235In this section, you will create the various pages that your application
236displays.
237
2381.  In the **OnlineOrder.cs** file in Visual Studio, replace the
239    existing namespace definition with the following code:
240
241        namespace FrontendWebRole.Models
242        {
243            public class OnlineOrder
244            {
245                public string Customer { get; set; }
246                public string Product { get; set; }
247            }
248        }
249
2502.  In **Solution Explorer**, double-click
251    **Controllers\HomeController.cs**. Add the following **using**
252    statements at the top of the file to include the namespaces for the
253    model you just created, as well as Service Bus:
254
255        using FrontendWebRole.Models;
256        using Microsoft.ServiceBus.Messaging;
257        using Microsoft.ServiceBus;
258
2593.  Also in the **HomeController.cs** file in Visual Studio, replace the
260    existing namespace definition with the following code. This code
261    contains methods for handling the submission of items to the queue:
262
263        namespace FrontendWebRole.Controllers
264        {
265            public class HomeController : Controller
266            {
267                public ActionResult Index()
268                {
269                    // Simply redirect to Submit, since Submit will serve as the
270                    // front page of this application
271                    return RedirectToAction("Submit");
272                }
273
274                public ActionResult About()
275                {
276                    return View();
277                }
278
279                // GET: /Home/Submit
280                // Controller method for a view you will create for the submission
281                // form
282                public ActionResult Submit()
283                {
284                    // Will put code for displaying queue message count here.
285
286                    return View();
287                }
288
289                // POST: /Home/Submit
290                // Controler method for handling submissions from the submission
291                // form 
292                [HttpPost]
293				// Attribute to help prevent cross-site scripting attacks and 
294				// cross-site request forgery  
295    			[ValidateAntiForgeryToken] 
296                public ActionResult Submit(OnlineOrder order)
297                {
298                    if (ModelState.IsValid)
299                    {
300                        // Will put code for submitting to queue here.
301                    
302                        return RedirectToAction("Submit");
303                    }
304                    else
305                    {
306                        return View(order);
307                    }
308                }
309            }
310        }
311
3124.  From the **Build** menu, click **Build Solution**.
313
3145.  Now, you will create the view for the **Submit()** method you
315    created above. Right-click within the Submit() method, and choose
316    **Add View**
317
318    ![][14]
319
3206.  A dialog appears for creating the view. Click the checkbox for
321    **Create a strongly-typed view**. In addition, select the
322    **OnlineOrder** class in the **Model class** dropdown, and choose
323    **Create** under the **Scaffold template** dropdown.
324
325    ![][15]
326
3277.  Click **Add**.
328
3298.  Now, you will change the displayed name of your application. In the
330    **Solution Explorer**, double-click the
331    **Views\Shared\\_Layout.cshtml** file to open it in the Visual
332    Studio editor.
333
3349.  Replace all occurrences of **My ASP.NET MVC Application** with
335    **LITWARE'S Awesome Products**.
336
33710.	Replace **"your logo here"** with **LITWARE'S Awesome Products**:
338
339	![][16]
340
34111. Remove the **Home**, **About**, and **Contact** links. Delete the highlighted code:
342
343	![][28]
344  
345
34612. Finally, modify the submission page to include some information about
347    the queue. In the **Solution Explorer**, double-click the
348    **Views\Home\Submit.cshtml** file to open it in the Visual Studio
349    editor. Add the following line after **&lt;h2>Submit&lt;/h2>**. For now,
350    the **ViewBag.MessageCount** is empty. You will populate it later.
351
352        <p>Current Number of Orders in Queue Waiting to be Processed: @ViewBag.MessageCount</p>
353             
354
35513. You now have implemented your UI. You can press **F5** to run your
356    application and confirm that it looks as expected.
357
358    ![][17]
359
360### Write the code for submitting items to a Service Bus queue
361
362Now, you will add code for submitting items to a queue. You will first
363create a class that contains your Service Bus Queue connection
364information. Then, you will initialize your connection from
365**Global.aspx.cs**. Finally, you will update the submission code you
366created earlier in **HomeController.cs** to actually submit items to a
367Service Bus Queue.
368
3691.  In Solution Explorer, right-click **FrontendWebRole** (right-click the project, not the role). Click **Add**, and then click **Class**.
370
3712.  Name the class **QueueConnector.cs**. Click **Add** to create the class.
372
3733.  You will now paste in code that encapsulates your connection
374    information and contains methods for initializing the connection to
375    a Service Bus Queue. In QueueConnector.cs, paste in the following code, and enter in
376    values for **Namespace**, **IssuerName**, and **IssuerKey**. You can
377    find these values in the [Management Portal][Windows Azure Management Portal].
378
379        using System;
380        using System.Collections.Generic;
381        using System.Linq;
382        using System.Web;
383        using Microsoft.ServiceBus.Messaging;
384        using Microsoft.ServiceBus;
385
386        namespace FrontendWebRole
387        {
388            public static class QueueConnector
389            {
390                // Thread-safe. Recommended that you cache rather than recreating it
391                // on every request.
392                public static QueueClient OrdersQueueClient;
393
394                // Obtain these values from the Management Portal
395                public const string Namespace = "your service bus namespace";
396                public const string IssuerName = "issuer name";
397                public const string IssuerKey = "issuer key";
398
399                // The name of your queue
400                public const string QueueName = "OrdersQueue";
401
402                public static NamespaceManager CreateNamespaceManager()
403                {
404                    // Create the namespace manager which gives you access to
405                    // management operations
406                    var uri = ServiceBusEnvironment.CreateServiceUri(
407                        "sb", Namespace, String.Empty);
408                    var tP = TokenProvider.CreateSharedSecretTokenProvider(
409                        IssuerName, IssuerKey);
410                    return new NamespaceManager(uri, tP);
411                }
412
413                public static void Initialize()
414                {
415                    // Using Http to be friendly with outbound firewalls
416                    ServiceBusEnvironment.SystemConnectivity.Mode = 
417                        ConnectivityMode.Http;
418
419                    // Create the namespace manager which gives you access to 
420                    // management operations
421                    var namespaceManager = CreateNamespaceManager();
422
423                    // Create the queue if it does not exist already
424                    if (!namespaceManager.QueueExists(QueueName))
425                    {
426                        namespaceManager.CreateQueue(QueueName);
427                    }
428
429                    // Get a client to the queue
430                    var messagingFactory = MessagingFactory.Create(
431                        namespaceManager.Address, 
432                        namespaceManager.Settings.TokenProvider);
433                    OrdersQueueClient = messagingFactory.CreateQueueClient(
434                        "OrdersQueue");
435                }
436            }
437        }
438
4394.  Now, you will ensure your **Initialize** method gets called. In the
440    **Solution Explorer**, double-click **Global.asax\Global.asax.cs**.
441
4425.  Add the following line to the bottom of the **Application_Start**
443    method:
444
445        FrontendWebRole.QueueConnector.Initialize();
446
4476.  Finally, you will update your web code you created earlier, to
448    submit items to the queue. In the **Solution Explorer**,
449    double-click **Controllers\HomeController.cs** that you created
450    earlier.
451
4527.  Update the **Submit()** method as follows to get the message count
453    for the queue:
454
455        public ActionResult Submit()
456        {            
457            // Get a NamespaceManager which allows you to perform management and
458            // diagnostic operations on your Service Bus Queues.
459            var namespaceManager = QueueConnector.CreateNamespaceManager();
460
461            // Get the queue, and obtain the message count.
462            var queue = namespaceManager.GetQueue(QueueConnector.QueueName);
463            ViewBag.MessageCount = queue.MessageCount;
464
465            return View();
466        }
467
4688.  Update the **Submit(OnlineOrder order)** method as follows to submit
469    order information to the queue:
470
471        public ActionResult Submit(OnlineOrder order)
472        {
473            if (ModelState.IsValid)
474            {
475                // Create a message from the order
476                var message = new BrokeredMessage(order);
477                
478                // Submit the order
479                QueueConnector.OrdersQueueClient.Send(message);
480                return RedirectToAction("Submit");
481            }
482            else
483            {
484                return View(order);
485            }
486        }
487
4889.  You can now run your application again. Each time you submit an
489    order, the message count increases.
490
491    ![][18]
492
493<h2><span class="short-header">Configuration manager</span>Cloud configuration manager</h2>
494
495Windows Azure supports a set of managed APIs that provides a consistent way to create new instances of Windows Azure service clients (such as the Service Bus) across Microsoft cloud services. These APIs enable you to instantiate these clients (for example, **CloudBlobClient**, **QueueClient**, **TopicClient**) regardless of where the application is hosted -- on-premises, in a Microsoft cloud service, in web sites, or in a persistent VM Role. You can also use these APIs to retrieve the configuration information necessary for instantiating these clients, and to change the configuration without having to redeploy the calling application. The APIs are located in the [Microsoft.WindowsAzure.Configuration.CloudConfigurationManager][] class. There are also APIs on the client side.
496
497### Connection string
498
499To instantiate a client (for example, a Service Bus **QueueClient**), you can represent the configuration information as a connection string. On the client side, there is a **CreateFromConnectionString()** method that instantiates that client type by using that connection string. For example, given the following configuration section:
500
501	<ConfigurationSettings>
502    ...
503    	<Setting name="Microsoft.ServiceBus.ConnectionString" value="Endpoint=sb://[yourServiceNamespace].servicebus.windows.net/;SharedSecretIssuer=[issuerName];SharedSecretValue=[yourDefaultKey]" />
504	</ConfigurationSettings>
505
506The following code retrieves the connection string, creates a queue, and initializes the connection to the queue:
507
508	QueueClient Client; 
509
510	string connectionString =
511     CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
512	
513    var namespaceManager =
514     NamespaceManager.CreateFromConnectionString(connectionString); 
515
516	if (!namespaceManager.QueueExists(QueueName))
517    {
518        namespaceManager.CreateQueue(QueueName);
519    }
520
521	// Initialize the connection to Service Bus Queue
522	Client = QueueClient.CreateFromConnectionString(connectionString, QueueName);
523
524The code in the following section uses these configuration management APIs.
525
526<h2><span class="short-header">Create worker role</span>Create the worker role</h2>
527
528You will now create the worker role that processes the order
529submissions. This example uses the **Worker Role with Service Bus Queue** Visual Studio project template. First, you will use Server Explorer in Visual Studio to obtain the required credentials.
530
5311. From the menu bar in Visual Studio, choose **View**, and then click **Server Explorer**. A **Service Bus** node appears under **Windows Azure** within the Server Explorer hierarchy, as in the following figure.
532
533	![][21]
534
5352. In Server Explorer, expand **Windows Azure**, then right-click **Service Bus**, then click **Add New Connection**.
536
5373. In the **Add Connection** dialog, type the name of the service namespace, the issuer name, and the issuer key. Then click **OK** to connect.
538
539	![][22]
540
5414.  In Visual Studio, in **Solution Explorer** right-click the
542    **Roles** folder under the **MultiTierApp** project.
543
5445.  Click **Add**, and then click **New Worker Role Project**. The **Add New Role Project** dialog appears.
545
546	![][26]
547
5486.  In the **Add New Role Project dialog**, click **Worker Role with Service Bus Queue**, as in the following figure:
549
550	![][23]
551
5527.  In the **Name** box, name the project **OrderProcessingRole**. Then click **Add**.
553
5548.  In Server Explorer, right-click the name of your service namespace, then click **Properties**. In the Visual Studio **Properties** pane, the first entry contains a connection string that is populated with the service namespace endpoint containing the required authorization credentials. For example, see the following figure. Double-click **ConnectionString**, and then press **Ctrl+C** to copy this string to the clipboard.
555
556	![][24]
557
5589.  In Solution Explorer, right-click the **OrderProcessingRole** you created in step 7 (make sure that you right-click **OrderProcessingRole** under **Roles**, and not the class). Then click **Properties**.
559
56010.  In the **Settings** tab of the **Properties** dialog, click inside the **Value** box for **Microsoft.ServiceBus.ConnectionString**, and then paste the endpoint value you copied in step 8.
561
562	![][25]
563
56411.  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** project (right-click the project, not the role). Click **Add**, then click **Existing Item**.
565
56612. Browse to the subfolder for **FrontendWebRole\Models**, and double-click **OnlineOrder.cs** to add it to this project.
567
56813. Replace the value of the **QueueName** variable in **WorkerRole.cs** from `"ProcessingQueue"` to `"OrdersQueue"` as in the following code:
569
570		// The name of your queue
571		const string QueueName = "OrdersQueue";
572
57314. Add the following using statement at the top of the WorkerRole.cs file:
574
575		using FrontendWebRole.Models;
576
57715. In the `Run()` function, inside the `OnMessage` call, add the following code inside the `try` clause:
578
579		Trace.WriteLine("Processing", receivedMessage.SequenceNumber.ToString());
580		// View the message as an OnlineOrder
581		OnlineOrder order = receivedMessage.GetBody<OnlineOrder>();
582		Trace.WriteLine(order.Customer + ": " + order.Product, "ProcessingMessage");
583		receivedMessage.Complete();
584
58516.  You have completed the application. You can test the full
586    application as you did earlier, by 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
587    worker role by viewing the Windows Azure Compute Emulator UI. You
588    can do this by right-clicking the emulator icon in the notification
589    area of your taskbar and selecting **Show Compute Emulator UI**.
590
591    ![][19]
592
593    ![][20]
594
595<h2><a name="nextsteps"></a><span class="short-header">Next steps</span>Next steps</h2>  
596
597To learn more about Service Bus, see the following resources:  
598  
599* [Windows Azure Service Bus][sbmsdn]  
600* [Service Bus How To's][sbwacom]  
601* [How to Use Service Bus Queues][sbwacomqhowto]  
602
603To learn more about multi-tier scenarios, or to learn how to deploy an application to a cloud service, see:  
604
605* [.NET Multi-Tier Application Using Storage Tables, Queues, and Blobs][mutitierstorage]  
606
607You might want to implement the front-end of a multi-tier application in a Windows Azure Web Site instead of a Windows Azure Cloud Service. To learn more about the difference between web sites and cloud services, see [Windows Azure Execution Models][executionmodels].
608
609To implement the application you create in this tutorial as a standard web project instead of as a cloud service web role, follow the steps in this tutorial with the following differences:
610
6111. When you create the project, choose the **ASP.NET MVC 4 Web Application** project template in the **Web** category instead of the **Cloud Service** template in the **Cloud** category. Then follow the same directions for creating the MVC application, until you get to the **Cloud configuration manager** section.
612
6132. When you create the worker role, create it in a new, separate solution, similar to the original instructions for the web role. Now however, you're creating just the worker role in the cloud service project. Then follow the same directions for creating the worker role.
614
6153. You can test the front-end and back-end separately, or you can run both simultaneously in separate Visual Studio instances.
616
617To learn how to deploy the front end to a Windows Azure Web Site, see [Deploying an ASP.NET Web Application to a Windows Azure Web Site](http://www.windowsazure.com/en-us/develop/net/tutorials/get-started/). To learn how to deploy the back end to a Windows Azure Cloud Service, see [.NET Multi-Tier Application Using Storage Tables, Queues, and Blobs][mutitierstorage].
618
619
620  [0]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-01.png
621  [1]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-100.png
622  [sbqueuecomparison]: http://msdn.microsoft.com/en-us/library/windowsazure/hh767287.aspx
623  [2]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-101.png
624  [Get Tools and SDK]: http://go.microsoft.com/fwlink/?LinkId=271920
625  [3]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-3.png
626  
627  
628  
629  [Windows Azure Management Portal]: http://manage.windowsazure.com
630  [6]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/sb-queues-03.png
631  [7]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/sb-queues-04.png
632  [8]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-09.png
633  [9]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-10.jpg
634  [10]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-11.png
635  [11]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-02.png
636  [12]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-12.png
637  [13]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-13.png
638  [14]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-33.png
639  [15]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-34.png
640  [16]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-35.png
641  [17]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-36.png
642  [18]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-37.png
643  
644  [19]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-38.png
645  [20]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-39.png
646  [21]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/SBExplorer.png
647  [22]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/SBExplorerAddConnect.png
648  [23]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/SBWorkerRole1.png
649  [24]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/SBExplorerProperties.png
650  [25]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/SBWorkerRoleProperties.png
651  [26]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/SBNewWorkerRole.png
652  [27]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-27.png
653  [28]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-40.png
654  [30]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/sb-queues-09.png
655  [31]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/sb-queues-06.png
656  [32]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-41.png
657  [33]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-4-2-WebPI.png
658  [sbmsdn]: http://msdn.microsoft.com/en-us/library/windowsazure/ee732537.aspx  
659  [sbwacom]: /en-us/manage/services/service-bus/  
660  [sbwacomqhowto]: /en-us/develop/net/how-to-guides/service-bus-queues/  
661  [mutitierstorage]: /en-us/develop/net/tutorials/multi-tier-web-site/1-overview/ 
662  [executionmodels]: http://www.windowsazure.com/en-us/develop/net/fundamentals/compute/