Azure Service Fabric 101

In this blog post I will introduce you to Azure Service Fabric and get you familiar with how to start working with it.

PreReqs

  • Windows 8/8.1/10
  • Windows Server 2012 R2 (or greater)
  • Visual Studio 2015 (note: Community edition is free)

Azure Service Fabric is a platform for building distributed solutions. It is currently in public preview on Azure and the SDK can be downloaded here. For a overview of the service please read this documentation.

Although Service Fabric is designed to be run across a cluster of compute resources (physical machines, virtual machines, containers, etc.) it can, for development purposes, be ran on a single box. This is referred to as a one box deployment.

Once you have installed the SDK, run this Powershell command to allow the Service Fabric scripts to work correctly.
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force -Scope CurrentUser

Now you'll need to grab the Visual Studio Service Fabric Tools extension. You can get this in Visual Studio by going to Tools > Extensions and Updates... > Search for Service Fabric Tools > Install the extension.

You're all set to get started on some local Service Fabric development.

Hello World Stateful Service

Let's run you through a basic example of a Service Fabric application.

Note: Visual Studio must be launched in Administrator mode

In Visual Studio create a new Service Fabric project as shown below

Once you select OK, a dialog box will open with a selection of service types prompting you to create one. Let's select a Reliable Stateful Service, give it a name and press OK.

This is required as the minimum number of services in a Service Fabric cluster is 1.

Once that has been created, you'll notice you have 2 projects in your solution.
The default project, Application4 in my case, is your Service Fabric project (*.sfproj). This contains Service Fabric specific items such as deployment parameters, deployment scripts and publishing profiles. The key item in this project is the ApplicationManfiest.xml which defines all your services and parameters. I'll dive into this in a later blog.

If you open up you stateful service project (*.csproj) you will see something similar to this.
Nothing too scary in here. You have a program.cs which is very similar to the default Program.cs file you get when you create a blank console application. It just has a main() method which defines the entry point for all CSharp applications. Inside the main function you will see some very well documented code. All that is doing is registering your stateful service with the Service Fabric runtime, printing a log and then sleeping forever to keep the program alive.

You will also notice a file with the same name as your project - i.e. MyStatefulService.cs. If you open that up, again you will find some very well documented code inside. There will be 2 methods CreateServiceReplicaListeners() and RunAsync(). At this stage I will not get into the details of what replicas are - just note that this method allows you to create and return an array of communication listeners (http, tcp, etc.). The RunAsync() method is fairly intuitive, it will be invoked by the Service Fabric runtime when the service is ready to start work. Although not strictly enforced - you should always honour the cancelServicePartitionReplica cancellation token which is passed into this method to make sure your service plays nice with Service Fabric.

In the default stateful service there is some code to increment a value from a IReliableDictionary with key Counter-1. There is some important concepts here. Service Fabric defines 2 ReliableCollection classes; ReliableDictionary and ReliableQueue. These work in very much the same way as the standard .NET collection classes - although they provide persistence. In this example you will notice that any operation on the ReliableDictionary is performed within this code block:

using (var tx = this.StateManager.CreateTransaction())
{// Operate on ReliableCollections here...}

This ensures transactional consistency (it either all works, or it all fails) for operations on the collections.
This transaction is embedded within a while loop with a 1 second delay after each cycle. What this effectively means is that the value associated with the key Counter-1 in the dictionary will be incremented every second.

Back to the Solution Explorer and we'll look at a few of the other files.

The ServiceEventSource.cs is a fairly complicated beast under the covers - but all you really need to know for now is that it can be used to produce events from your service - such as log messages.

Packages.config contains references to the NuGet packages in your project. This will be populated with 3 Service Fabric packages in this case.

Microsoft.ServiceFabric
Microsoft.ServiceFabric.Data
Microsoft.ServiceFabric.Services

App.config is a standard application configuration file that exists in most .NET projects, see here.

The PackageRoot directory contains another directory called config and a file ServiceManifest.xml.

The ServiceManifest.xml is another important file. This file is where you define attributes about your service, like endpoints, names and versions. Again I will dive into this in further detail in a later post.

Now we understand all the files in our project. We know that the main() method in the Program.cs file will register our service with the Service Fabric runtime, which will then initialise the service and finally invoke the RunAsync() method on our service. In our default example - this will increment a counter stored in a ReliableDictionary with the key Counter-1 every second until the service is terminated. We should expect the ReliableDictionary to persist our data - so once the service starts back up the counter should continue from where it left off.

I have not explained how Service Fabric manages this state persistence in this post, but I do aim to cover it in future posts.

Build and run the Service Fabric project in Debug mode (F5)

When you build and run your Service Fabric project for the first time, Visual Studio will invoke Service Fabric scripts to create a local Service Fabric cluster. A diagnostics event viewer will open in Visual Studio logging events from your cluster. You should see a number being incremented - as we expected.

You should also be able to see a new icon in your system tray:

Right clicking on this icon will give you some options to control your Service Fabric cluster. Select Manage Local Cluster or navigate to http://localhost:19080/Explorer/ in your browser. This will load Service Fabric Explorer which is a dashboard for your cluster. You'll notice there are 2 applications currently running in your cluster. One of these is the Service Fabric system services and the other is your stateful service. Fully expand each of the groups in the left hand panel until it looks something like this:

I will again cover what all this means in a different blog post

Take note of the Node which has the (Primary) label next to it, in my case Node.5.
Now if you open Task Manager in Windows you should see 3 versions of your stateful service running. If you right click on each you can see which node they are hosted on.

Find your primary node, and then kill it with the End Task button. This will force Service Fabric to failover and will test the state persistence. Again I'm not going to cover how this works under the covers in this blog post. If you switch back to Visual Studio and look in your diagnostic logs you should see that the service has continued to count. Now back in the cluster explorer, you should notice your (Primary) label has moved to another node.

The state has been persisted and the service didn't drop even during a failure. That is a key feature of Service Fabric. There is a lot that happens in the background to facilitate this high availability and the cluster orchestration which I will cover in subsequent blogs.

You have now built and run your first Service Fabric application. Now you need to right click on the Service Fabric icon in your system tray and stop the cluster, you may wish to remove the cluster as well if you want to do a full cleanup.

Note: The life time of the cluster and your services is not tied to Visual Studio. Even when you stop debugging, your services will continue to run until you explicitly stop them in the Cluster Explorer or using Powershell.