Understanding Azure Service Fabric: Microsoft’s Next Generation PaaS Platform

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Azure Service Fabric (ASF) Platform

Service Fabric Platform is the next generation platform-as-a-service offering from Microsoft Azure. It has been released as a developer preview in May, 2015 and the expected GA release is early 2016. It is also termed as PaaS 2.0 that not only supports stateless services but also stateful services to build highly performant, reliable, and scalable enterprise applications. Today’s Internet scale applications consist of a combination of stateless and stateful microservices. Stateless microservices act as protocol gateways or web proxies that do not maintain any mutable state outside of their request and response. The current Microsoft PaaS 1.0 mainly provides a worker and Web role as stateless services that can’t maintain their own state. On the other hand, stateful microservices (user info, product info, shopping carts, and so forth) maintain a mutable state beyond their request and response. Microsoft claims that this is the same technology that powers their Cloud infrastructure, and many other services such as Skype for business, Even Hubs, DocumentDB, and Azure SQL Databases (maintaining more than million databases).

So, Azure Service Fabric is the framework to rapidly break down a complex business problem into reliable and scalable stateless or stateful microservices. The resulting architecture would look like that in Figure 1, where the front end services are load balanced to handle the request from end users while many stateful microservices do the actual work behind the scenes. Because data can be reliably persisted in the service, we don’t have to fetch or save data from an external store for every request.

Fabric1
Figure 1: Application design with Service Fabric

Azure Service Fabric (PaaS 2.0) Advantages

The major difference between Azure PaaS 1.0 and PaaS 2.0 is the introduction of stateful services in the later version. Now, with Azure Service Fabric, we can create stateful services that can hold data reliably between multiple replicas deployed on multiple nodes (VM). This removes the need for using caching services, queues, or database calls to fetch or save data for every request.

Fabric2
Figure 2: Simplistic architecture of Service Fabric vs. existing cloud services

Service Fabric targets to achieve the following goals that are not easy to achieve using PaaS 1.0 (Web role or Worker roles):

  1. The ability to build efficient, high-throughput, low-latency, fault-tolerant services such as modern ecommerce applications, IoT systems, and next generation enterprise applications that solve complex business problem with a vast amount of data. Stateful services have fewer moving parts and hence naturally are highly available with low-latency.
  2. Higher utilization of available resources (VM): Service Fabric deploys primary and many secondary replicas on multiple nodes (VMs) and each VM can share multiple services. In PaaS 1.0, cloud services in the form of a worker or Web role used to take the whole VM, which was not an optimal use of computing resources.

Fabric3
Figure 3: Service Fabric deployment of primary and many secondary replicas

Service Fabric Programming Models

Service Fabric offers two high-level frameworks for building services. Although both of these programming frameworks are built on the same Service Fabric core, they are targeted to solve different kinds of business problems. These two frameworks are:

  • Reliable Actors APIs: Actors are similar to .NET objects as they encapsulate not only state but also their behaviors. For example: An ecommerce site can have many Actors such as Order, Product, Invoice, and User uniquely identified by ACTOR_ID and distributed on various nodes across a cluster. Each of these Actors can interact asynchronously in a request-response pattern with other Actors or services.
  • Reliable Services APIs: Traditionally or in the WCF world, services require external systems (out of process) for reliable state management. Service Fabric gives us Reliable Collections, which is similar to C# generic collections to store state along with the service in the same process (co-location). This reliable state gets replicated to all the replicas in various nodes to provide high reliability and availability with reduced latency. A pluggable communication model makes it even more powerful to use out of the box listeners or create a custom communication listener to support any kinds of transport protocols: HTTP, TCP, and so on.

Both of these programming models have pros and cons, and so it would be quite obvious to use a combination approach where reliable services might consume many actor services to implement any business usecase.

Getting Started with Service Fabric

Scenario: Create a number counting console application using a Stateful service.

Set Up Development Environment

  • Operating System: Windows 8+/Windows Server 2012 R2
  • Visual Studio:
    • 2015: Use community preview (available in Azure Gallery under the Visual Studio category). It supports the Service Fabric application type and has templates to create stateful or stateless services.
    • 2013: We can create ASF services by using a console project type that copies all the DLLs and manifest files to an ASF package.
  • Install SDK: Azure SDK 2.7 and Service Fabric SDK targeting specific Visual studio version (links are VS 2015, VS 2013).
  • Configure Development/Local cluster:

    This will enable PowerShell script execution; and Install and start a local cluster.

    In PowerShell (as Administrator), run the following command:

    Set-ExecutionPolicy -ExecutionPolicy Unrestricted
       -Force -Scope CurrentUser
    & "$env:ProgramW6432\Microsoft SDKs\Service
       Fabric\ClusterSetup\DevClusterSetup.ps1"
    
  • Verify local cluster setup: Open Service Fabric Explorer from “C:\Program Files\Microsoft SDKs\Service Fabric\Tools\ServiceFabricExplorer\ServiceFabricExplorer.exe

    The following will open:

    Fabric4
    Figure 4: The Service Fabric Explorer

Create a Stateful Service

With Visual Studio 2015, we can create a stateful service by selecting an installed template.

Fabric5
Figure 5: Selecting a template

In VS 2013, you can create a console app and follow these steps to create a stateful service:

  1. Create a console app and a stateful service (explained below).
  2. Set up post build events to create a package.
xcopy /R /Y "$(ProjectDir)Manifests\
   ApplicationManifest.xml"
   "$(ApplicationPackagePath)\"
xcopy /R /Y "$(ProjectDir)Manifests\
   ServiceManifest.xml"
   "$(ServicePackagePath)\"
xcopy /R /Y "*"
   "$(ServicePackagePath)\Code\"
  1. Add variables to the project file.
       <PropertyGroup>
          <ApplicationPackagePath>$(TargetDir)
             NumberCounterAppType
             </ApplicationPackagePath>
          <ServicePackagePath>
             $(ApplicationPackagePath)\
             NumberCountingServicePkg
          </ServicePackagePath>
       </PropertyGroup>
    

The Solution would look like the following:

Fabric6
Figure 6: The finished Solution

Explanation of a Few Important Solution Components

Service Registration to Fabric Runtime

This is the ServiceType that is registered with FabricRuntime.

using (FabricRuntime fabricRuntime = FabricRuntime.Create())
{
   fabricRuntime.RegisterServiceType("NumberCountingServiceType",
      typeof(NumberCountingService));
   Thread.Sleep(Timeout.Infinite);
}

NumberCountingService

This is the main stateful service extending StatefulService and implementing WCF contract INumberCounter that is available to clients through a WCF listener.

public class NumberCountingService : StatefulService,
   INumberCounter
{
   protected override ICommunicationListener
      CreateCommunicationListener()
   {
      return new WcfCommunicationListener(typeof(INumberCounter),
         this)
      {

         EndpointResourceName = "ServiceEndpoint",
         Binding = CreateListenBinding()
      };
   }

   protected override async Task RunAsync(CancellationToken
      cancellationToken)
   {
      .....
   }

   public async Task<long> GetCurrentNumber()
   {
      .....
   }
}

State Persistence

There are two types of reliable collections available in reliable service: IReliableQueue<T> and IReliableDictionary<T1,T2>. The base class StateManager property is used to persist the collection in service and its replicas.

var numbersDic = await this.StateManager.GetOrAddAsync
   <IReliableDictionary<string, long>>("numbersDic");
using (var tx = this.StateManager.CreateTransaction())
{
   var result = await numbersDic.TryGetValueAsync(tx,
      "Counter-1");

   await numbersDic.AddOrUpdateAsync(tx, "Counter-1",
      0, (k, v) => ++v);
   await tx.CommitAsync();
}

Word Counting Client

The NumCountingSvcClient class for creating a proxy wrapper to connect to the Fabric Services.

class NumCountingSvcClient : ServicePartitionClient
   <WcfCommunicationClient<INumberCounter>>,
   INumberCounter
{
   public NumCountingSvcClient(
      WcfCommunicationClientFactory<INumberCounter>
         clientFactory,
      Uri serviceName)
      : base(clientFactory, serviceName)
      {
      }

   public Task<long> GetCurrentNumber()
   {
      return this.InvokeWithRetryAsync(
         client => client.Channel.GetCurrentNumber());
      }
   }

Creating Client Instance and Calling Service Method

ServicePartitionResolver serviceResolver = new
   ServicePartitionResolver(() => new FabricClient() { });

// Binding for WCF
NetTcpBinding binding = CreateClientConnectionBinding();

Var client = new NumCountingSvcClient(new
   WcfCommunicationClientFactory<INumberCounter>
   (serviceResolver, binding, null, null), ServiceName);

Manifest Files

ApplicationManifest: It defines the application type and the service types contained within the application package.

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest ApplicationTypeName="NumberCounterAppType"
      ApplicationTypeVersion="1.0.0.0"
      
      xmlns_xsd="http://www.w3.org/2001/XMLSchema"
      xmlns_xsi="http://www.w3.org/2001/XMLSchema-instance">
   <Parameters>
      .....
   </Parameters>
   <ServiceManifestImport>
      <ServiceManifestRef ServiceManifestName=
         "NumberCountingServicePkg"
         ServiceManifestVersion="1.0.0.0" />
   </ServiceManifestImport>
   <DefaultServices>
      <Service Name="NumberCountingService">
         <StatefulService ServiceTypeName=
               "NumberCountingServiceType"
               TargetReplicaSetSize="3" MinReplicaSetSize="2">
            <SingletonPartition  />
         </StatefulService>
      </Service>
   </DefaultServices>
</ApplicationManifest>

ServiceManifest: It defines the Service Fabric service type, code (EXE) and endpoint configurations associated with service package.

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="NumberCountingServicePkg"
                 Version="1.0.0.0"
                 
                 xmlns_xsd="http://www.w3.org/2001/
                    XMLSchema"
                 xmlns_xsi="http://www.w3.org/2001/
                    XMLSchema-instance">
   <ServiceTypes>
      <StatefulServiceType ServiceTypeName=
         "NumberCountingServiceType"
         HasPersistedState="true" />
   </ServiceTypes>

   <CodePackage Name="Code" Version="1.0.0.0">
      <EntryPoint>
         <ExeHost>
            <Program>NumberCountingService.exe</Program>
         </ExeHost>
      </EntryPoint>
   </CodePackage>
   <ConfigPackage Name="Config" Version="1.0.0.0" />
      <Resources>
         <Endpoints>
            <Endpoint Name="ServiceEndpoint" />
            <Endpoint Name="ReplicatorEndpoint" />
         </Endpoints>
      </Resources>
</ServiceManifest>

Deployment to a Local Cluster

Deployment package: Service package contains following:

  • NumberCountingServicePkg: Code, Config, and ServiceManifest
  • ApplicationManifest

Deploy Using Visual Studio 2015: Right-click Service Fabric application and click “Publish”. It will use the default Local publish profile.

Deploy Using Visual Studio 2013: Use the following PowerShell script to remove and deploy services.

Script to deploy to local cluster:

$dp0 = Split-Path -parent $PSCommandPath
$SolutionDir = (Get-Item "$dp0\..\").FullName
$applicationPath = "$SolutionDir"+"bin\
   Debug\NumberCounterAppType"
Connect-ServiceFabricCluster "localhost:19000"
Copy-ServiceFabricApplicationPackage
   -ApplicationPackagePath $applicationPath
   -ImageStoreConnectionString fabric:ImageStore
Register-ServiceFabricApplicationType
   -ApplicationPathInImageStore NumberCounterApp
New-ServiceFabricApplication
   -ApplicationName fabric:/NumberCounterApp
   -ApplicationTypeName NumberCounterApp
   -ApplicationTypeVersion 1.0
New-ServiceFabricService
   -ApplicationName fabric:/NumberCounterApp
   -ServiceName fabric:/NumberCounterApp/NumberCountingService
   -ServiceTypeName NumberCountingServiceType
   -Stateful
   -HasPersistedState
   -PartitionSchemeSingleton
   -TargetReplicaSetSize 2
   -MinReplicaSetSize 2

Script to remove from local cluster:

Connect-ServiceFabricCluster "localhost:19000"
Remove-ServiceFabricService
   -ServiceName fabric:/NumberCounterApp/NumberCountingService
   -Force
Remove-ServiceFabricApplication
   -ApplicationName fabric:/NumberCounterApp
   -Force
Unregister-ServiceFabricApplicationType
   -ApplicationTypeName NumberCounterAppType
   -ApplicationTypeVersion 1.0.0.0
   -Force
Remove-ServiceFabricApplicationPackage
   -ApplicationPackagePathInImageStore NumberCounterAppType
   -ImageStoreConnectionString  fabric:ImageStore

Sample Code

The complete sample code has been uploaded to github at https://github.com/manoj-kumar1/ServiceFabric-NumberCountingApp. This solution has been developed using Visual Studio 2015. It can be opened using Visual Studio 2013, but the Service Fabric application project won’t open and the extra steps would be required as explained above for Visual Studio 2013 environment setup and deployment.

Summary

Service Fabric is a platform-as-a-service framework from Azure to build hyper-scale, highly reliable, and easily-managed applications for the cloud. It addresses many of the significant challenges in developing and managing cloud applications.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read