PageRenderTime 44ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://github.com/jeffwilcox/azure-content
Markdown | 678 lines | 481 code | 197 blank | 0 comment | 0 complexity | 30e9c0678395791b48715b32a53103c7 MD5 | raw file
  1. <properties urlDisplayName="Multi-Tier Application" pageTitle=".NET Multi-Tier Application - 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 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="sethm" solutions="" manager="timlt" editor="mattshel" />
  2. <tags ms.service="service-bus" ms.workload="tbd" ms.tgt_pltfrm="na" ms.devlang="dotnet" ms.topic="article" ms.date="09/15/2014" ms.author="sethm" />
  3. # .NET Multi-Tier Application Using Service Bus Queues
  4. Developing for Azure is easy using Visual Studio 2013 and the
  5. free Azure SDK for .NET. If you do not already have Visual
  6. Studio 2013, the SDK will automatically install Visual Studio Express 2013, so you can start developing for Azure entirely for
  7. free. This guide assumes you have no prior experience using Windows
  8. Azure. On completing this guide, you will have an application that uses
  9. multiple Azure resources running in your local environment and
  10. demonstrating how a multi-tier application works.
  11. You will learn:
  12. - How to enable your computer for Azure development with a
  13. single download and install.
  14. - How to use Visual Studio to develop for Azure.
  15. - How to create a multi-tier application in Azure using web
  16. and worker roles.
  17. - How to communicate between tiers using Service Bus Queues.
  18. [WACOM.INCLUDE [create-account-note](../includes/create-account-note.md)]
  19. In this tutorial you'll build and run the multi-tier application in an 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 an Azure Website instead of a cloud service. For instructions about what to do differently an Azure Website front end, see the [Next steps](#nextsteps) section.
  20. A screenshot of the completed application is shown below:
  21. ![][0]
  22. **Note** Azure also provides storage queue functionality. For more information about Azure storage queues and Service Bus queues, see [Azure Queues and Azure Service Bus Queues - Compared and Contrasted][sbqueuecomparison].
  23. <h2><span class="short-header">Inter-role communication</span>Scenario overview: inter-role communication</h2>
  24. To submit an order for processing, the front end UI component, running
  25. in the web role, needs to interact with the middle tier logic running in
  26. the worker role. This example uses Service Bus brokered messaging for
  27. the communication between the tiers.
  28. Using brokered messaging between the web and middle tiers decouples the
  29. two components. In contrast to direct messaging (that is, TCP or HTTP),
  30. the web tier does not connect to the middle tier directly; instead it
  31. pushes units of work, as messages, into the Service Bus, which reliably
  32. retains them until the middle tier is ready to consume and process them.
  33. The Service Bus provides two entities to support brokered messaging:
  34. queues and topics. With queues, each message sent to the queue is
  35. consumed by a single receiver. Topics support the publish/subscribe
  36. pattern in which each published message is made available to each
  37. subscription registered with the topic. Each subscription logically
  38. maintains its own queue of messages. Subscriptions can also be
  39. configured with filter rules that restrict the set of messages passed to
  40. the subscription queue to those that match the filter. This example uses
  41. Service Bus queues.
  42. ![][1]
  43. This communication mechanism has several advantages over direct
  44. messaging, namely:
  45. - **Temporal decoupling.** With the asynchronous messaging pattern,
  46. producers and consumers need not be online at the same time. Service
  47. Bus reliably stores messages until the consuming party is ready to
  48. receive them. This allows the components of the distributed
  49. application to be disconnected, either voluntarily, for example, for
  50. maintenance, or due to a component crash, without impacting the
  51. system as a whole. Furthermore, the consuming application may only
  52. need to come online during certain times of the day.
  53. - **Load leveling**. In many applications, system load varies over
  54. time whereas the processing time required for each unit of work is
  55. typically constant. Intermediating message producers and consumers
  56. with a queue means that the consuming application (the worker) only
  57. needs to be provisioned to accommodate average load rather than peak
  58. load. The depth of the queue will grow and contract as the incoming
  59. load varies. This directly saves money in terms of the amount of
  60. infrastructure required to service the application load.
  61. - **Load balancing.** As load increases, more worker processes can be
  62. added to read from the queue. Each message is processed by only one
  63. of the worker processes. Furthermore, this pull-based load balancing
  64. allows for optimum utilization of the worker machines even if the
  65. worker machines differ in terms of processing power as they will
  66. pull messages at their own maximum rate. This pattern is often
  67. termed the competing consumer pattern.
  68. ![][2]
  69. The following sections discuss the code that implements this
  70. architecture.
  71. <h2><span class="short-header">Set up environment</span>Set up the development environment</h2>
  72. Before you can begin developing your Azure application, you need
  73. to get the tools and set-up your development environment.
  74. 1. To install the Azure SDK for .NET, click the button below:
  75. [Get Tools and SDK][]
  76. 2. Click **install the SDK**.
  77. 3. Choose the link for the version of Visual Studio you are using. The steps in this tutorial use Visual Studio 2013:
  78. ![][32]
  79. 4. When prompted to run or save the installation file, click
  80. **Run**:
  81. ![][3]
  82. 5. In the Web Platform Installer, click **Install** and proceed with the installation:
  83. ![][33]
  84. 6. Once the installation is complete, you will have everything
  85. necessary to start developing. The SDK includes tools that let you
  86. easily develop Azure applications in Visual Studio. If you
  87. do not have Visual Studio installed, it also installs the free
  88. Visual Studio Express for Web.
  89. <h2><span class="short-header">Set up the namespace</span>Set up the Service Bus namespace</h2>
  90. The next step is to create a service namespace, and to obtain a shared
  91. secret key. A service namespace provides an application boundary for
  92. each application exposed through Service Bus. A shared secret key is
  93. automatically generated by the system when a service namespace is
  94. created. The combination of service namespace and shared secret key
  95. provides a credential for Service Bus to authenticate access to an
  96. application.
  97. Note that you can also manage namespaces and Service Bus messaging entities using the Visual Studio Server Explorer, but you can only create new namespaces from within the portal.
  98. ###Set up the namespace using the Management Portal
  99. 1. Log into the [Azure Management Portal][].
  100. 2. In the left navigation pane of the Management Portal, click
  101. **Service Bus**.
  102. 3. In the lower pane of the Management Portal, click **Create**.
  103. ![][6]
  104. 4. In the **Add a new namespace** dialog, enter a namespace name.
  105. The system immediately checks to see if the name is available.
  106. ![][7]
  107. 5. After making sure the namespace name is available, choose the
  108. country or region in which your namespace should be hosted (make
  109. sure you use the same country/region in which you are deploying your
  110. compute resources).
  111. IMPORTANT: Pick the **same region** that you intend to choose for
  112. deploying your application. This will give you the best performance.
  113. 6. Click the check mark. The system now creates your service
  114. namespace and enables it. You might have to wait several minutes as
  115. the system provisions resources for your account.
  116. ![][27]
  117. 7. In the main window, click the name of your service namespace.
  118. ![][30]
  119. 8. Click **Connection Information**.
  120. ![][31]
  121. 9. In the **Access connection information** pane, find the **Default Issuer** and **Default Key** values.
  122. 10. Make a note of the key, or copy it to the clipboard.
  123. ###Manage namespaces and messaging entities using the Visual Studio Server Explorer
  124. To manage a namespace and obtain connection information using Visual Studio instead of the Management Portal, follow the procedure described [here](http://http://msdn.microsoft.com/en-us/library/windowsazure/ff687127.aspx), in the section titled **To connect to Azure from Visual Studio**. When you sign in to Azure, the **Service Bus** node under the **Microsoft Azure** tree in Server Explorer is automatically populated with any namespaces you've already created. Right-click any namespace, and then click **Properties** to see the connection string and other metadata associated with this namespace displayed in the Visual Studio **Properties** pane.
  125. Make a note of the **SharedAccessKey** value, or copy it to the clipboard:
  126. ![][34]
  127. <h2><span class="short-header">Create a web role</span>Create a web role</h2>
  128. In this section, you will build the front end of your application. You
  129. will first create the various pages that your application displays.
  130. After that, you will add the code for submitting items to a Service Bus
  131. Queue and displaying status information about the queue.
  132. ### Create the project
  133. 1. Using administrator privileges, start either Microsoft Visual Studio
  134. 2013 or Microsoft Visual Studio Express. To start Visual
  135. Studio with administrator privileges, right-click **Microsoft Visual
  136. Studio 2013 (or Microsoft Visual Studio Express)** and
  137. then click **Run as administrator**. The Azure compute emulator,
  138. discussed later in this guide, requires that Visual Studio be
  139. launched with administrator privileges.
  140. In Visual Studio, on the **File** menu, click **New**, and then
  141. click **Project**.
  142. ![][8]
  143. 2. From **Installed Templates**, under **Visual C#**, click **Cloud** and
  144. then click **Azure Cloud Service**. Name the project
  145. **MultiTierApp**. Then click **OK**.
  146. ![][9]
  147. 3. From **.NET Framework 4.5** roles, double-click **ASP.NET Web
  148. Role**.
  149. ![][10]
  150. 4. Hover over **WebRole1** under **Azure Cloud Service solution**, click
  151. 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".)
  152. ![][11]
  153. 5. From the **New ASP.NET Project** dialog, in the **Select a template** list, click **MVC**,
  154. then click **OK**.
  155. ![][12]
  156. 6. In **Solution Explorer**, right-click **References**, then click
  157. **Manage NuGet Packages...** or **Add Library Package Reference**.
  158. 7. Select **Online** on the left-hand side of the dialog. Search for
  159. "**WindowsAzure**" and select the **Azure Service
  160. Bus** item. Then complete the installation and close this dialog.
  161. ![][13]
  162. 8. Note that the required client assemblies are now referenced and some
  163. new code files have been added.
  164. 9. In **Solution Explorer**, right click **Models** and click **Add**,
  165. then click **Class**. In the Name box, type the name
  166. **OnlineOrder.cs**. Then click **Add**.
  167. ### Write the code for your web role
  168. In this section, you will create the various pages that your application
  169. displays.
  170. 1. In the **OnlineOrder.cs** file in Visual Studio, replace the
  171. existing namespace definition with the following code:
  172. namespace FrontendWebRole.Models
  173. {
  174. public class OnlineOrder
  175. {
  176. public string Customer { get; set; }
  177. public string Product { get; set; }
  178. }
  179. }
  180. 2. In **Solution Explorer**, double-click
  181. **Controllers\HomeController.cs**. Add the following **using**
  182. statements at the top of the file to include the namespaces for the
  183. model you just created, as well as Service Bus:
  184. using FrontendWebRole.Models;
  185. using Microsoft.ServiceBus.Messaging;
  186. using Microsoft.ServiceBus;
  187. 3. Also in the **HomeController.cs** file in Visual Studio, replace the
  188. existing namespace definition with the following code. This code
  189. contains methods for handling the submission of items to the queue:
  190. namespace FrontendWebRole.Controllers
  191. {
  192. public class HomeController : Controller
  193. {
  194. public ActionResult Index()
  195. {
  196. // Simply redirect to Submit, since Submit will serve as the
  197. // front page of this application
  198. return RedirectToAction("Submit");
  199. }
  200. public ActionResult About()
  201. {
  202. return View();
  203. }
  204. // GET: /Home/Submit
  205. // Controller method for a view you will create for the submission
  206. // form
  207. public ActionResult Submit()
  208. {
  209. // Will put code for displaying queue message count here.
  210. return View();
  211. }
  212. // POST: /Home/Submit
  213. // Controller method for handling submissions from the submission
  214. // form
  215. [HttpPost]
  216. // Attribute to help prevent cross-site scripting attacks and
  217. // cross-site request forgery
  218. [ValidateAntiForgeryToken]
  219. public ActionResult Submit(OnlineOrder order)
  220. {
  221. if (ModelState.IsValid)
  222. {
  223. // Will put code for submitting to queue here.
  224. return RedirectToAction("Submit");
  225. }
  226. else
  227. {
  228. return View(order);
  229. }
  230. }
  231. }
  232. }
  233. 4. From the **Build** menu, click **Build Solution**.
  234. 5. Now, you will create the view for the **Submit()** method you
  235. created above. Right-click within the Submit() method, and choose
  236. **Add View**
  237. ![][14]
  238. 6. A dialog appears for creating the view. Select the
  239. **OnlineOrder** class in the **Model class** dropdown, and choose
  240. **Create** in the **Template** dropdown.
  241. ![][15]
  242. 7. Click **Add**.
  243. 8. Now, you will change the displayed name of your application. In the
  244. **Solution Explorer**, double-click the
  245. **Views\Shared\\_Layout.cshtml** file to open it in the Visual
  246. Studio editor.
  247. 9. Replace all occurrences of **My ASP.NET MVC Application** with
  248. **LITWARE'S Awesome Products**.
  249. 10. Replace **"your logo here"** with **LITWARE'S Awesome Products**:
  250. ![][16]
  251. 11. Remove the **Home**, **About**, and **Contact** links. Delete the highlighted code:
  252. ![][28]
  253. 12. Finally, modify the submission page to include some information about
  254. the queue. In **Solution Explorer**, double-click the
  255. **Views\Home\Submit.cshtml** file to open it in the Visual Studio
  256. editor. Add the following line after **&lt;h2>Submit&lt;/h2>**. For now,
  257. the **ViewBag.MessageCount** is empty. You will populate it later.
  258. <p>Current Number of Orders in Queue Waiting to be Processed: @ViewBag.MessageCount</p>
  259. 13. You now have implemented your UI. You can press **F5** to run your
  260. application and confirm that it looks as expected.
  261. ![][17]
  262. ### Write the code for submitting items to a Service Bus queue
  263. Now, you will add code for submitting items to a queue. You will first
  264. create a class that contains your Service Bus Queue connection
  265. information. Then, you will initialize your connection from
  266. **Global.aspx.cs**. Finally, you will update the submission code you
  267. created earlier in **HomeController.cs** to actually submit items to a
  268. Service Bus Queue.
  269. 1. In Solution Explorer, right-click **FrontendWebRole** (right-click the project, not the role). Click **Add**, and then click **Class**.
  270. 2. Name the class **QueueConnector.cs**. Click **Add** to create the class.
  271. 3. You will now paste in code that encapsulates your connection
  272. information and contains methods for initializing the connection to
  273. a Service Bus Queue. In QueueConnector.cs, paste in the following code, and enter in
  274. values for **Namespace**, **IssuerName**, and **IssuerKey**. You can
  275. obtain these values either from the [Management Portal][Azure Management Portal], or from the Visual Studio Server Explorer under the **Service Bus** node.
  276. using System;
  277. using System.Collections.Generic;
  278. using System.Linq;
  279. using System.Web;
  280. using Microsoft.ServiceBus.Messaging;
  281. using Microsoft.ServiceBus;
  282. namespace FrontendWebRole
  283. {
  284. public static class QueueConnector
  285. {
  286. // Thread-safe. Recommended that you cache rather than recreating it
  287. // on every request.
  288. public static QueueClient OrdersQueueClient;
  289. // Obtain these values from the Management Portal
  290. public const string Namespace = "your service bus namespace";
  291. public const string IssuerName = "issuer name";
  292. public const string IssuerKey = "issuer key";
  293. // The name of your queue
  294. public const string QueueName = "OrdersQueue";
  295. public static NamespaceManager CreateNamespaceManager()
  296. {
  297. // Create the namespace manager which gives you access to
  298. // management operations
  299. var uri = ServiceBusEnvironment.CreateServiceUri(
  300. "sb", Namespace, String.Empty);
  301. var tP = TokenProvider.CreateSharedSecretTokenProvider(
  302. IssuerName, IssuerKey);
  303. return new NamespaceManager(uri, tP);
  304. }
  305. public static void Initialize()
  306. {
  307. // Using Http to be friendly with outbound firewalls
  308. ServiceBusEnvironment.SystemConnectivity.Mode =
  309. ConnectivityMode.Http;
  310. // Create the namespace manager which gives you access to
  311. // management operations
  312. var namespaceManager = CreateNamespaceManager();
  313. // Create the queue if it does not exist already
  314. if (!namespaceManager.QueueExists(QueueName))
  315. {
  316. namespaceManager.CreateQueue(QueueName);
  317. }
  318. // Get a client to the queue
  319. var messagingFactory = MessagingFactory.Create(
  320. namespaceManager.Address,
  321. namespaceManager.Settings.TokenProvider);
  322. OrdersQueueClient = messagingFactory.CreateQueueClient(
  323. "OrdersQueue");
  324. }
  325. }
  326. }
  327. 4. Now, you will ensure your **Initialize** method gets called. In **Solution Explorer**, double-click **Global.asax\Global.asax.cs**.
  328. 5. Add the following line to the bottom of the **Application_Start**
  329. method:
  330. FrontendWebRole.QueueConnector.Initialize();
  331. 6. Finally, you will update your web code you created earlier, to
  332. submit items to the queue. In **Solution Explorer**,
  333. double-click **Controllers\HomeController.cs** that you created
  334. earlier.
  335. 7. Update the **Submit()** method as follows to get the message count
  336. for the queue:
  337. public ActionResult Submit()
  338. {
  339. // Get a NamespaceManager which allows you to perform management and
  340. // diagnostic operations on your Service Bus Queues.
  341. var namespaceManager = QueueConnector.CreateNamespaceManager();
  342. // Get the queue, and obtain the message count.
  343. var queue = namespaceManager.GetQueue(QueueConnector.QueueName);
  344. ViewBag.MessageCount = queue.MessageCount;
  345. return View();
  346. }
  347. 8. Update the **Submit(OnlineOrder order)** method as follows to submit
  348. order information to the queue:
  349. public ActionResult Submit(OnlineOrder order)
  350. {
  351. if (ModelState.IsValid)
  352. {
  353. // Create a message from the order
  354. var message = new BrokeredMessage(order);
  355. // Submit the order
  356. QueueConnector.OrdersQueueClient.Send(message);
  357. return RedirectToAction("Submit");
  358. }
  359. else
  360. {
  361. return View(order);
  362. }
  363. }
  364. 9. You can now run your application again. Each time you submit an
  365. order, the message count increases.
  366. ![][18]
  367. <h2><span class="short-header">Configuration manager</span>Cloud configuration manager</h2>
  368. Azure supports a set of managed APIs that provides a consistent way to create new instances of 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 websites, 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.
  369. ### Connection string
  370. To 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:
  371. <ConfigurationSettings>
  372. ...
  373. <Setting name="Microsoft.ServiceBus.ConnectionString" value="Endpoint=sb://[yourServiceNamespace].servicebus.windows.net/;SharedSecretIssuer=[issuerName];SharedSecretValue=[yourDefaultKey]" />
  374. </ConfigurationSettings>
  375. The following code retrieves the connection string, creates a queue, and initializes the connection to the queue:
  376. QueueClient Client;
  377. string connectionString =
  378. CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
  379. var namespaceManager =
  380. NamespaceManager.CreateFromConnectionString(connectionString);
  381. if (!namespaceManager.QueueExists(QueueName))
  382. {
  383. namespaceManager.CreateQueue(QueueName);
  384. }
  385. // Initialize the connection to Service Bus Queue
  386. Client = QueueClient.CreateFromConnectionString(connectionString, QueueName);
  387. The code in the following section uses these configuration management APIs.
  388. <h2><span class="short-header">Create worker role</span>Create the worker role</h2>
  389. You will now create the worker role that processes the order
  390. submissions. 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.
  391. 1. If you've already connected Visual Studio to your Azure account, as described in the section **Set up the namespace using the Visual Studio Server Explorer,** skip ahead to step 5.
  392. 3. From the menu bar in Visual Studio, choose **View**, and then click **Server Explorer**. A **Service Bus** node appears under **Azure** within the Server Explorer hierarchy, as in the following figure.
  393. ![][21]
  394. 2. In Server Explorer, expand **Azure**, then right-click **Service Bus**, then click **Add New Connection**.
  395. 3. In the **Add Connection** dialog, type the name of the service namespace, the issuer name, and the issuer key. Then click **OK** to connect.
  396. ![][22]
  397. 4. In Visual Studio, in **Solution Explorer** right-click the
  398. **Roles** folder under the **MultiTierApp** project.
  399. 5. Click **Add**, and then click **New Worker Role Project**. The **Add New Role Project** dialog appears.
  400. ![][26]
  401. 6. In the **Add New Role Project dialog**, click **Worker Role with Service Bus Queue**, as in the following figure:
  402. ![][23]
  403. 7. In the **Name** box, name the project **OrderProcessingRole**. Then click **Add**.
  404. 8. 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.
  405. ![][24]
  406. 9. 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**.
  407. 10. 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.
  408. ![][25]
  409. 11. 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**.
  410. 12. Browse to the subfolder for **FrontendWebRole\Models**, and double-click **OnlineOrder.cs** to add it to this project.
  411. 13. In WorkerRole.cs, replace the value of the **QueueName** variable in **WorkerRole.cs** from `"ProcessingQueue"` to `"OrdersQueue"` as in the following code:
  412. // The name of your queue
  413. const string QueueName = "OrdersQueue";
  414. 14. Add the following using statement at the top of the WorkerRole.cs file:
  415. using FrontendWebRole.Models;
  416. 15. In the `Run()` function, inside the `OnMessage` call, add the following code inside the `try` clause:
  417. Trace.WriteLine("Processing", receivedMessage.SequenceNumber.ToString());
  418. // View the message as an OnlineOrder
  419. OnlineOrder order = receivedMessage.GetBody<OnlineOrder>();
  420. Trace.WriteLine(order.Customer + ": " + order.Product, "ProcessingMessage");
  421. receivedMessage.Complete();
  422. 16. You have completed the application. You can test the full
  423. 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
  424. worker role by viewing the Azure Compute Emulator UI. You
  425. can do this by right-clicking the emulator icon in the notification
  426. area of your taskbar and selecting **Show Compute Emulator UI**.
  427. ![][19]
  428. ![][20]
  429. <h2><a name="nextsteps"></a><span class="short-header">Next steps</span>Next steps</h2>
  430. To learn more about Service Bus, see the following resources:
  431. * [Azure Service Bus][sbmsdn]
  432. * [Service Bus How To's][sbwacom]
  433. * [How to Use Service Bus Queues][sbwacomqhowto]
  434. To learn more about multi-tier scenarios, or to learn how to deploy an application to a cloud service, see:
  435. * [.NET Multi-Tier Application Using Storage Tables, Queues, and Blobs][mutitierstorage]
  436. You might want to implement the front-end of a multi-tier application in an Azure Website instead of an Azure Cloud Service. To learn more about the difference between websites and cloud services, see [Azure Execution Models][executionmodels].
  437. To 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:
  438. 1. 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.
  439. 2. 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.
  440. 3. You can test the front-end and back-end separately, or you can run both simultaneously in separate Visual Studio instances.
  441. To learn how to deploy the front end to an Azure Website, see [Deploying an ASP.NET Web Application to an Azure Website](http://www.windowsazure.com/en-us/develop/net/tutorials/get-started/). To learn how to deploy the back end to an Azure Cloud Service, see [.NET Multi-Tier Application Using Storage Tables, Queues, and Blobs][mutitierstorage].
  442. [0]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-01.png
  443. [1]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-100.png
  444. [sbqueuecomparison]: http://msdn.microsoft.com/en-us/library/windowsazure/hh767287.aspx
  445. [2]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-101.png
  446. [Get Tools and SDK]: http://go.microsoft.com/fwlink/?LinkId=271920
  447. [3]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-3.png
  448. [Azure Management Portal]: http://manage.windowsazure.com
  449. [6]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/sb-queues-03.png
  450. [7]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/sb-queues-04.png
  451. [8]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-09.png
  452. [9]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-10.jpg
  453. [10]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-11.png
  454. [11]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-02.png
  455. [12]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-12.png
  456. [13]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-13.png
  457. [14]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-33.png
  458. [15]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-34.png
  459. [16]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-35.png
  460. [17]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-36.png
  461. [18]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-37.png
  462. [19]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-38.png
  463. [20]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-39.png
  464. [21]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/SBExplorer.png
  465. [22]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/SBExplorerAddConnect.png
  466. [23]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/SBWorkerRole1.png
  467. [24]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/SBExplorerProperties.png
  468. [25]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/SBWorkerRoleProperties.png
  469. [26]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/SBNewWorkerRole.png
  470. [27]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-27.png
  471. [28]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-multi-tier-40.png
  472. [30]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/sb-queues-09.png
  473. [31]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/sb-queues-06.png
  474. [32]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-41.png
  475. [33]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/getting-started-4-2-WebPI.png
  476. [34]: ./media/cloud-services-dotnet-multi-tier-app-using-service-bus-queues/VSProperties.png
  477. [sbmsdn]: http://msdn.microsoft.com/en-us/library/windowsazure/ee732537.aspx
  478. [sbwacom]: /en-us/documentation/services/service-bus/
  479. [sbwacomqhowto]: /en-us/develop/net/how-to-guides/service-bus-queues/
  480. [mutitierstorage]: /en-us/develop/net/tutorials/multi-tier-web-site/1-overview/
  481. [executionmodels]: http://www.windowsazure.com/en-us/develop/net/fundamentals/compute/