PageRenderTime 31ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

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

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