{"id":213,"date":"2014-09-16T15:11:37","date_gmt":"2014-09-16T15:11:37","guid":{"rendered":"http:\/\/looselycoupledlabs.com\/?p=213"},"modified":"2014-11-26T16:31:21","modified_gmt":"2014-11-26T16:31:21","slug":"masstransit-on-microsoft-azure-2","status":"publish","type":"post","link":"https:\/\/looselycoupledlabs.com\/2014\/09\/masstransit-on-microsoft-azure-2\/","title":{"rendered":"MassTransit on Microsoft Azure"},"content":{"rendered":"
In my first post on this blog<\/a>, I showed you how to get a simple Publish\/Subscribe example working very quickly using MassTransit<\/a> and RabbitMQ<\/a>. I\u2019d always planned to show you how to move that example to the cloud, with Microsoft Azure being a compelling competitor in this space, especially for the .NET developer (though not exclusively for .NET). Let\u2019s take a look at some of the cool things we can take advantage of in the cloud, including auto-scaling our subscribers to match the load of messages being published.<\/p>\n As discussed in my first post, the first thing you need is a message queuing framework. MassTransit supports MSMQ, RabbitMQ, and others. I really like RabbitMQ for this role for a variety of reasons, but since we\u2019ve already looked at RabbitMQ in a number of previous posts, I thought it would make sense to take a look at Azure Service Bus. Since we\u2019re going to be deploying to Azure, it makes a lot of sense to consider this as an option.<\/p>\n Thankfully, there is a MassTransit transport for Azure Service Bus (find the source on GitHub here<\/a>). While we could have setup a RabbitMQ server or two using Azure Virtual Machines (either Windows or Linux), it is easier to get going on Azure by using the Azure Service Bus. Also, as we\u2019ll find out later, when you use the Azure Service Bus, you can tie your cloud service scaling to the size of your message queue.<\/p>\n If you don\u2019t have a Microsoft Azure account yet, head over to to azure.microsoft.com<\/a> and get signed up for a free trial. (Also, MSDN subscribers have free Azure services as part of their subscription. If you have an MSDN subscription, you only need to activate your Azure account.)<\/p>\n Next, in the Azure Portal<\/a>, click \u201cService Bus\u201d button in the left-hand list of areas. Then, click the \u201cCreate a New Namespace\u201d button:<\/p>\n In the dialog, pick a name for your new namespace (in this example, I will use the name \u201cLoosely,\u201d but you will have to choose a unique name). Choose a region and be sure to leave Type as \u201cMessaging:\u201d<\/p>\n When you click the OK button, Azure will create and activate your new Azure Service Bus namespace. There\u2019s nothing else to setup at this time as MassTransit will automatically create the queues and topics that it will require for your publish\/subscribe code.<\/p>\n In order to be able to create cloud services easily in Visual Studio, you should install the Azure SDK. This can be downloaded from the Azure Downloads page<\/a>. Download the VS 2013 or 2012 install under the .NET heading, depending on your version of Visual Studio.<\/p>\n I used Visual Studio 2013 to create this sample, but it should work in 2012 as well. You can get the entire source from: https:\/\/github.com\/dprothero\/MtPubSubAzureExample<\/a><\/p>\n I like to use the concept of a \u201ccontract\u201d for my messages I want to put onto the service bus. This is an interface definition that both the publisher and subscriber have to agree upon. They don\u2019t need to know anything about the implementation of this interface on either side. To keep the publisher and subscriber as loosely coupled as possible, I like to put my contracts in their own assembly so that this is the only shared dependency.<\/p>\n So, the first step is to create a new solution called MtPubSubAzureExample and a new class library called \u201cContracts\u201d. To the class library, add a single interface called \u201cSomethingHappened.\u201d<\/p>\n SomethingHappened will be the message interface we use for our sample message. Our publisher will create an instance of a class implementing SomethingHappened, set What and When properties, and publish it onto the service bus.<\/p>\n Our subscriber will then set up a subscription (aka Consumer) to listen for all messages of type SomethingHappened. MassTransit will call our Consumer class whenever a SomethingHappened message is received, and we can handle it as we wish, presumably inspecting the What and the When properties.<\/p>\n When you\u2019re writing a new project from scratch, you go through many permutations and refactor as you go. Initially, this example had the service bus setup code duplicated in both the publisher and subscriber projects. This is fine, particularly if you really aren\u2019t in a position to share much code between the two sides (except the contracts of course). However, in my case, I preferred to use a common class which I\u2019ll call \u201cAzureBusInitializer\u201d to set up my instance to MassTransit and get it configured.<\/p>\n So, add another class library to the MtPubSubAzureExample solution and name it \u201cConfiguration\u201d. Before creating our class, it\u2019s time to head to NuGet and pull in MassTransit. The quickest way to get everything you need is to find the MassTransit.AzureServiceBus package and install that. Doing so will install all of MassTransit and its dependencies.<\/p>\n You still need one more package. I found that MassTransit doesn\u2019t work unless you install one of the logging integration packages that are designed for it. For me, I selected the Log4Net integration package (MassTransit.Log4Net).<\/p>\n Now, create a new class called \u201cAzureBusInitializer.\u201d<\/p>\n We\u2019re creating a static method called \u201cCreateBus,\u201d which both our publisher and subscriber can use to set up an instance of a bus, using the Log4NetLogger, and connecting to our Azure Service Bus namespace. Because there may be additional custom setup that the publisher or subscriber may want to do, we allow passing in a lambda expression to perform the additional setup.<\/p>\n I\u2019ve highlighted a couple lines that will require App.config settings in our publisher and subscriber apps. Or, you can hard-code the values here. You should know your namespace name (as you just created it). To find your access key, you can click on the \u201cConnection Information\u201d button in the lower toolbar in the Azure Portal:<\/p>\n The key will be the \u201cSharedAccessKey\u201d parameter in the connection string. For example:<\/p>\n We\u2019ll make the publisher a very simple console application that just prompts the user for a number of messages they\u2019d like to publish and then publish that many SomethingHappened messages. Add a new Console Application project called \u201cTestPublisher\u201d to the solution and add a new class called \u201cSomethingHappenedMessage.\u201d This will be our concrete implementation of the SomethingHappened interface. You\u2019ll need to add a project reference to the Contracts (and add one to Configuration too, while you\u2019re at it).<\/p>\n Now, in the Main method of the Program.cs file in your Console Application, you can put in the code to set up the bus, prompt the user for the number of messages they want to publish, and publish that many messages onto the bus. Real quick first, however, add a NuGet reference to the MassTransit package.<\/p>\n Pretty simple, huh? We put the input capture and message publishing in a loop to make it easy to send multiple messages. Just put a catch for the string \u201cquit\u201d so we can exit the publisher when we\u2019d like. Be sure to update the app.config for TestPublisher to include your Azure key and namespace:<\/p>\n If you make TestPublisher the startup project of the solution and run it, right now you can publish messages all you like\u2026. However, nobody is listening yet!<\/p>\n The final piece of the puzzle! Add another Console Application project to your solution and call it TestSubscriber. Again, add project references to Contracts and Configuration and then add the MassTransit NuGet package.<\/p>\n The first thing we need is a Consumer class to consume the SomethingHappened messages. Add a new class to the console app and call it \u201cSomethingHappenedConsumer.\u201d<\/p>\n This consumer class implements a specific MassTransit interface whose Consume method will be called with the message context and SomethingHappened message each time a message is received. Here we are simply writing the message out to the console.<\/p>\n Finally, in the Main method of Program.cs, we can initialize the bus and, as part of the initialization, instruct MassTransit that we wish to subscribe to messages of type SomethingHappened.<\/p>\n Now right-click on the MtPubSubAzureExample solution in the solution explorer and choose \u201cSet Startup Projects\u2026.\u201d From here, choose the Multiple startup projects option and set the Action for both TestPublisher and TestSubscriber to Start. Now when you run your solution, both the publisher and subscriber will run. Again, be sure to update the app.config for TestSubscriber to include your Azure key and namespace like you did for TestPublisher.<\/p>\n Publish some messages from the publisher window. You should see them show up immediately in the subscriber window!<\/p>\n Now close just<\/em> the Subscriber sample window and publish a few more messages in the Publisher window.<\/p>\n Go ahead and close the Publisher window for now. Let\u2019s take a deeper look at where those three messages went.<\/p>\n Go back into the Azure Portal, select your namespace, and click on the the Topics tab. You\u2019ll see a new topic called contracts..somethinghappened. In Azure Service Bus, queues can be subscribers to a topic. You\u2019ll see the topic has a \u201c1\u201d in Subscriptions Count:<\/p>\n Click on the \u201ccontracts..somethinghappened\u201d topic and then click on the \u201cSubscriptions\u201d tab. You will see that there is a single queue subscribed to the topic named \u201cMtPubSubAzureExample_TestSubscriberXXXXXX:\u201d<\/p>\n So, by creating a subscription from our TestSubscriber, MassTransit automatically set up a topic subscription for us!<\/p>\n Now, click on the \u201cQueues\u201d tab and you will see that the queue \u201cmtpubsubazureexample_testsubscriber\u201d has 3 messages (the \u201cQueue Length\u201d column):<\/p>\n Fire up the TestSubscriber app, and you should see it process the three messages left in the queue.<\/p>\n Notice the timestamp from the message versus the timestamp of when the subscriber actually published the message. In this case, there was a 7-minute lag (the 7 minutes we were poking around in Azure before starting up the subscriber again).<\/p>\n Now that we have a simple publish\/subscribe example working, let\u2019s have our subscriber actually run in the cloud. There\u2019s a number of ways we could do this, but probably the most \u201ccloudy\u201d way to do it would be to create an Azure Cloud Service. These are extremely easy to create in Visual Studio 2013 (assuming you\u2019ve installed the Azure SDK as instructed at the beginning of this post).<\/p>\n Add a new project to your MtPubSubAzureExample solution and choose \u201cAzure Cloud Service\u201d from the list of project templates. Name the new project \u201cTestCloudSubscriber\u201d. A cloud setup dialog will appear next. Select \u201cWorker Role\u201d only as we will be creating a background service that processes messages using MassTransit. Rename the \u201cWorkerRole1\u201d to \u201cTestCloudSubscriberWorker.\u201d<\/p>\n This will add the TestCloudSubscriber and TestCloudSubscriberWorker projects and drop you into the WorkerRole.cs file in TestCloudSubscriberWorker. As always, be sure to update the app.config for TestCloudSubscriberWorker to include your Azure key and namespace. Add a project reference to the Configuration and Contracts projects and add the MassTransit NuGet package to the new worker project.<\/p>\n Copy the SomethingHappenedConsumer.cs file from TestSubscriber to TestCloudSubscriberWorker. Edit the namespace of SomethingHappenedConsumer.cs to be \u201cTestCloudSubscriberWorker\u201d and change the Console.WriteLine to a call to Trace.TraceInformation:<\/p>\n Now, edit the top of WorkerRole.cs to add-in a couple usings and a private field for our service bus:<\/p>\n Then, edit the OnStart() method to initialize the bus and our subscriptions:<\/p>\n And edit the OnStop() method to dispose of the bus:<\/p>\n Right-click on the MtPubSubAzureExample solution and choose \u201cSet StartUp Projects\u2026\u201d Choose \u201cMultiple startup projects\u201d and set the Action to Start for TestPublisher and TestCloudSubscriber (the TestCloudSubscriber will startup our TestCloudSubscriberWorker). Run the solution and you should see your familiar TestPublisher console window. Where is the TestCloudSubscriber service? Look in your tray for the Azure emulator icon:<\/p>\n Right-click and choose \u201cShow Compute Emulator UI\u201d and then click on the \u201cTestCloudSubscriberWorker\u201d in the tree view. This should bring up the console for the cloud service which should be displaying the trace messages. You should see \u201cWorking\u201d every 1 second, since that\u2019s what the Worker Role code template does:<\/p>\n If we publish some messages from the TestPublisher, we should see them get handled in the emulator console:<\/p>\n Now we want to actually run the TestCloudSubscriber, well, in the cloud! Right-click on the TestCloudSubscriber project and select \u201cPublish.\u201d This will bring up the \u201cPublish Azure Application\u201d dialog. After signing in, another dialog should popup titled \u201cCreate Cloud Service and Storage Account.\u201d Give it any name you like and choose the region (you probably want the same region where you created your Azure Service Bus):<\/p>\n Then, on the Settings tab of the Publish wizard, simply click the Publish button. This will publish your cloud service to Azure, which you\u2019ll be able to see under Cloud Services in the Azure Portal:<\/p>\n Click on your service and then click on the \u201cInstances\u201d tab:<\/p>\n As you can see, our first instance of our service is running. Back in Visual Studio, you can right-click on the TestPublisher project and set it as the sole startup project. Run it and publish a few messages to the bus. Our cloud service should process the messages, but how can we be sure? The quick and dirty way is to check the Queue Length of the mtpubsubazureexample_testcloudsubscriber queue. As long as this is a decreasing number (or a zero), then our cloud service is processing the messages. If you want more than that and would like to actually see the trace messages we are writing out from our cloud service, read on.<\/p>\n Expand the \u201cRoles\u201d folder under the TestCloudSubscriber project in Visual Studio. Right-click on the TestCloudSubscriberWorker role and select \u201cProperties.\u201d On the Configuration tab, find the Diagnostics section and change \u201cErrors only\u201d to \u201cAll information.\u201d After doing so, re-publish your service to Azure and wait for it to restart.<\/p>\n Once it is up and running, publish a few more messages using TestPublisher. Now, in Visual Studio\u2019s Server Explorer, expand the Azure node, Storage, your storage account (e.g. testcloudsubscriber), Tables, and then double-click the \u201cWADLogsTable\u201d table. Here you can view all of the tracing messages from your cloud service. You should see your messages in the \u201cMessage\u201d column:<\/p>\n You probably don\u2019t want to run your service with the \u201cAll information\u201d option set all the time, but we do get a warm fuzzy feeling knowing everything is being processed the way we expect!<\/p>\n Azure has a great and stupid simple way to automatically scale out your cloud service based on the number of messages in your queue. In the Azure Portal, simply navigate to your Cloud Service and click the \u201cScale\u201d tab. Next to \u201cScale by Metric,\u201d choose \u201cQueue\u201d:<\/p>\n Under \u201cInstance Range,\u201d choose your upper limit of instances (e.g. 5):<\/p>\n Select the Namespace and Queue Name you want to \u201cwatch\u201d and tie your service scaling to:<\/p>\n Finally, set \u201cTarget per Machine\u201d to how many messages you want a single instance to be able to handle at any given time. For example, if you have a single instance running, and the number of messages in the queue exceeds this number, then Azure will spin up another instance based on the above rules.<\/p>\n Thanks Azure! In order to test this out, I actually stopped the cloud service so it wasn\u2019t processing messages and then published 400,000 messages. I restarted the cloud service and it ran with one instance for a while, but pretty soon, it started launching new instances, based on my configuration (which I had dialed back pretty far to make sure the scaling would get triggered). It worked great, and that backlog of messages was worked down to zero in no time.<\/p>\n Hopefully, this post was helpful in getting you off the ground with MassTransit and Azure. Most of the topics dealt with in my previous articles dealing with MassTransit and RabbitMQ can also be applied to running MassTransit in Azure and with Azure Service Bus (with the exception of RabbitMQ specific topics). I hope to see you back here soon and, as always, please let me know if you have any questions or suggestions for future topics!<\/p>\n Until then\u2026<\/p>\n","protected":false},"excerpt":{"rendered":" In my first post on this blog, I showed you how to get a simple Publish\/Subscribe example working very quickly using MassTransit and RabbitMQ. I\u2019d always planned to show you how to move that example to the cloud, with Microsoft Azure being a compelling competitor in this space, especially for the .NET developer (though not… Continue reading Setting Up Your Environment<\/h1>\n
<\/h2>\n
Choosing the Right Messaging Platform<\/h2>\n
Setting Up Azure Service Bus<\/h2>\n
<\/a><\/p>\n
<\/a><\/p>\n
Install the Azure SDK<\/h2>\n
Creating the Sample Applications<\/h1>\n
Creating a Contract<\/h2>\n
using System;\r\n\r\nnamespace Contracts\r\n{\r\n public interface SomethingHappened\r\n {\r\n string What { get; }\r\n DateTime When { get; }\r\n }\r\n}<\/pre>\n
Shared Configuration Setup Code<\/h2>\n
using MassTransit;\r\nusing MassTransit.BusConfigurators;\r\nusing MassTransit.Log4NetIntegration.Logging;\r\nusing MassTransit.Transports.AzureServiceBus;\r\nusing System;\r\nusing System.Configuration;\r\n\r\nnamespace Configuration\r\n{\r\n public class AzureBusInitializer\r\n {\r\n public static IServiceBus CreateBus(string queueName, Action<ServiceBusConfigurator> moreInitialization)\r\n {\r\n Log4NetLogger.Use();\r\n var bus = ServiceBusFactory.New(sbc =>\r\n {\r\n var azureNameSpace = GetConfigValue(\"azure-namespace\", \"YourNamespace\");\r\n var queueUri = \"azure-sb:\/\/\" + azureNameSpace + \"\/MtPubSubAzureExample_\" + queueName;\r\n\r\n sbc.ReceiveFrom(queueUri);\r\n SetupAzureServiceBus(sbc, azureNameSpace);\r\n\r\n moreInitialization(sbc);\r\n });\r\n\r\n return bus;\r\n }\r\n\r\n private static void SetupAzureServiceBus(ServiceBusConfigurator sbc, string azureNameSpace)\r\n {\r\n sbc.UseAzureServiceBus(a => a.ConfigureNamespace(azureNameSpace, h =>\r\n {\r\n h.SetKeyName(GetConfigValue(\"azure-keyname\", \"RootManageSharedAccessKey\"));\r\n h.SetKey(GetConfigValue(\"azure-key\", \"\"));\r\n }));\r\n sbc.UseAzureServiceBusRouting();\r\n }\r\n\r\n private static string GetConfigValue(string key, string defaultValue)\r\n {\r\n string value = ConfigurationManager.AppSettings[key];\r\n return string.IsNullOrEmpty(value) ? defaultValue : value;\r\n }\r\n\r\n }\r\n}\r\n<\/pre>\n
<\/a><\/p>\n
Endpoint=sb:\/\/loosely.servicebus.windows.net\/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=key-goes-here\r\n<\/pre>\n
Creating the Publisher<\/h2>\n
using Contracts;\r\nusing System;\r\n\r\nnamespace TestPublisher\r\n{\r\n class SomethingHappenedMessage : SomethingHappened\r\n {\r\n public string What { get; set; }\r\n public DateTime When { get; set; }\r\n }\r\n}<\/pre>\n
using Configuration;\r\nusing Contracts;\r\nusing System;\r\nusing System.Threading.Tasks;\r\n\r\nnamespace TestPublisher\r\n{\r\n class Program\r\n {\r\n static void Main(string[] args)\r\n {\r\n var bus = AzureBusInitializer.CreateBus(\"TestPublisher\", x => { });\r\n string text = \"\";\r\n\r\n while (text != \"quit\")\r\n {\r\n Console.Write(\"Enter number of messages to generate (quit to exit): \");\r\n text = Console.ReadLine();\r\n\r\n int numMessages = 0;\r\n if (int.TryParse(text, out numMessages) && numMessages > 0)\r\n {\r\n Parallel.For(0, numMessages, i =>\r\n {\r\n var message = new SomethingHappenedMessage() { What = \"message \" + i.ToString(), When = DateTime.Now };\r\n bus.Publish<SomethingHappened>(message, x => { x.SetDeliveryMode(MassTransit.DeliveryMode.Persistent); });\r\n });\r\n }\r\n else if(text != \"quit\")\r\n {\r\n Console.WriteLine(\"\\\"\" + text + \"\\\" is not a number.\");\r\n }\r\n }\r\n\r\n bus.Dispose();\r\n }\r\n }\r\n}\r\n<\/pre>\n
<appSettings>\r\n <add key=\"azure-namespace\" value=\"loosely\" \/>\r\n <add key=\"azure-key\" value=\"YourKeyHere\" \/>\r\n <\/appSettings>\r\n<\/pre>\n
Creating the Subscriber<\/h2>\n
using Contracts;\r\nusing MassTransit;\r\nusing System;\r\nusing System.Threading;\r\n\r\nnamespace TestSubscriber\r\n{\r\n class SomethingHappenedConsumer : Consumes<SomethingHappened>.Context\r\n {\r\n public void Consume(IConsumeContext<SomethingHappened> message)\r\n {\r\n Console.WriteLine(\"TXT: \" + message.Message.What +\r\n \" SENT: \" + message.Message.When.ToString() +\r\n \" PROCESSED: \" + DateTime.Now.ToString() + \r\n \" (\" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + \")\");\r\n\r\n \/\/ Simulate processing time\r\n Thread.Sleep(250);\r\n }\r\n }\r\n}\r\n<\/pre>\n
using Configuration;\r\nusing MassTransit;\r\nusing System;\r\n\r\nnamespace TestSubscriber\r\n{\r\n class Program\r\n {\r\n static void Main(string[] args)\r\n {\r\n var bus = AzureBusInitializer.CreateBus(\"TestSubscriber\", sbc =>\r\n {\r\n sbc.SetConcurrentConsumerLimit(64);\r\n sbc.Subscribe(subs =>\r\n {\r\n subs.Consumer<SomethingHappenedConsumer>().Permanent();\r\n });\r\n });\r\n\r\n Console.ReadKey();\r\n\r\n bus.Dispose();\r\n }\r\n }\r\n}\r\n<\/pre>\n
<\/a><\/p>\n
<\/a><\/p>\n
<\/h2>\n
What\u2019s Going on in Azure Service Bus?<\/h2>\n
<\/a><\/p>\n
<\/a><\/p>\n
<\/a><\/p>\n
<\/a><\/p>\n
<\/h1>\n
<\/h1>\n
<\/h2>\n
Run the Subscriber In the Cloud<\/h2>\n
<\/a><\/p>\n
using Contracts;\r\nusing MassTransit;\r\nusing System;\r\nusing System.Diagnostics;\r\nusing System.Threading;\r\n\r\nnamespace TestCloudSubscriberWorker\r\n{\r\n class SomethingHappenedConsumer : Consumes<SomethingHappened>.Context\r\n {\r\n public void Consume(IConsumeContext<SomethingHappened> message)\r\n {\r\n Trace.TraceInformation(\"TXT: \" + message.Message.What +\r\n \" SENT: \" + message.Message.When.ToString() +\r\n \" PROCESSED: \" + DateTime.Now.ToString() + \r\n \" (\" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + \")\");\r\n\r\n \/\/ Simulate processing time\r\n Thread.Sleep(250);\r\n }\r\n }\r\n}\r\n<\/pre>\n
using Configuration;\r\nusing MassTransit;\r\nusing Microsoft.WindowsAzure.ServiceRuntime;\r\nusing System.Diagnostics;\r\nusing System.Net;\r\nusing System.Threading;\r\nusing System.Threading.Tasks;\r\n\r\nnamespace TestCloudSubscriberWorker\r\n{\r\n public class WorkerRole : RoleEntryPoint\r\n {\r\n private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();\r\n private readonly ManualResetEvent runCompleteEvent = new ManualResetEvent(false);\r\n private IServiceBus _bus;\r\n<\/pre>\n
public override bool OnStart()\r\n{\r\n \/\/ Set the maximum number of concurrent connections\r\n ServicePointManager.DefaultConnectionLimit = 12;\r\n\r\n \/\/ For information on handling configuration changes\r\n \/\/ see the MSDN topic at http:\/\/go.microsoft.com\/fwlink\/?LinkId=166357.\r\n\r\n bool result = base.OnStart();\r\n\r\n if(result)\r\n {\r\n _bus = AzureBusInitializer.CreateBus(\"TestCloudSubscriber\", sbc =>\r\n {\r\n sbc.SetConcurrentConsumerLimit(64);\r\n sbc.Subscribe(subs =>\r\n {\r\n subs.Consumer<SomethingHappenedConsumer>().Permanent();\r\n });\r\n });\r\n }\r\n \r\n Trace.TraceInformation(\"TestCloudSubscriberWorker has been started\");\r\n\r\n return result;\r\n}\r\n<\/pre>\n
public override void OnStop()\r\n{\r\n Trace.TraceInformation(\"TestCloudSubscriberWorker is stopping\");\r\n\r\n this.cancellationTokenSource.Cancel();\r\n this.runCompleteEvent.WaitOne();\r\n\r\n if(_bus != null)\r\n _bus.Dispose();\r\n \r\n base.OnStop();\r\n\r\n Trace.TraceInformation(\"TestCloudSubscriberWorker has stopped\");\r\n}\r\n<\/pre>\n
<\/a><\/p>\n
<\/a><\/p>\n
<\/a><\/p>\n
Publish the Cloud Service to Azure<\/h2>\n
<\/a><\/p>\n
<\/a><\/p>\n
<\/a><\/p>\n
Viewing Full Trace Information<\/h2>\n
<\/a><\/p>\n
Scaling Out Your Subscribers<\/h2>\n
<\/a><\/p>\n
<\/a><\/p>\n
<\/a><\/p>\n
<\/a><\/p>\n
<\/a><\/p>\n
Wrap Up<\/h1>\n