Getting Started
Architecture
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Samples

Service Fabric Hosting

Component: NServiceBus
NuGet Package: NServiceBus (8.x)

NServiceBus endpoints can be hosted in Service Fabric using any of these three options:

  1. Stateless services
  2. Stateful services
  3. Guest executable

Refer to the Service Fabric documentation for more information on when to use each option.

Stateless service

Hosting with a stateless service is similar to self-hosting with Azure App Service). Endpoints are stateless and use storage external to Service Fabric to manage data needed for their operation. Endpoints can be scaled out, leveraging competing consumer at the transport level.

With stateless services, the number of service instances can range from one to the number of nodes in the cluster - 1. Endpoints are self-hosted and should be started using a custom Service Fabric ICommunicationListener implementation.

public class StatelessEndpointCommunicationListener :
    ICommunicationListener
{
    IEndpointInstance endpointInstance;

    public async Task<string> OpenAsync(CancellationToken cancellationToken)
    {
        var endpointName = "Sales";

        var endpointConfiguration = new EndpointConfiguration(endpointName);

        // endpoint configuration
        endpointInstance = await Endpoint.Start(endpointConfiguration);

        return endpointName;
    }

    public Task CloseAsync(CancellationToken cancellationToken)
    {
        return endpointInstance.Stop();
    }

    public void Abort()
    {
        CloseAsync(CancellationToken.None);
    }
}

Stateful service

The process of configuring and starting an endpoint hosted in a stateful service is very similar to the stateless service hosting approach. The main difference is that the endpoint cannot be started until the OpenAsync method has returned because the StateManager instance has not been fully configured yet. This is trivial to solve by calling the Endpoint.Start operation from the RunAsync operation instead.

public class StatefulEndpointCommunicationListener :
    ICommunicationListener
{
    IReliableStateManager stateManager;
    IEndpointInstance endpointInstance;
    EndpointConfiguration endpointConfiguration;

    public StatefulEndpointCommunicationListener(IReliableStateManager stateManager)
    {
        this.stateManager = stateManager;
    }

    public async Task<string> OpenAsync(CancellationToken cancellationToken)
    {
        var endpointName = "Sales";

        endpointConfiguration = new EndpointConfiguration(endpointName);

        // configure endpoint with state manager dependency

        return endpointName;
    }

    public async Task RunAsync()
    {
        endpointInstance = await Endpoint.Start(endpointConfiguration);
    }

    public Task CloseAsync(CancellationToken cancellationToken)
    {
        return endpointInstance.Stop();
    }

    public void Abort()
    {
        CloseAsync(CancellationToken.None);
    }
}
class MyStatefulService :
    StatefulService
{
    StatefulEndpointCommunicationListener listener;

    public MyStatefulService(StatefulServiceContext context)
        : base(context)
    { }

    protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
    {
        listener = new StatefulEndpointCommunicationListener(StateManager);
        return new List<ServiceReplicaListener>
        {
            new ServiceReplicaListener(context => listener)
        };
    }

    protected override Task RunAsync(CancellationToken cancellationToken)
    {
        return listener.RunAsync();
    }
}

Due to characteristics of stateful services, i.e. data partitioning and local data storage, additional configuration aspects must be considered:

  • The service partitioning schema must be well-defined before the first deployment occurs (repartitioning requires all data to be deleted)
  • Messages must be routed among the shards according to the partitioning schema
  • A single instance of an NServiceBus endpoint will be running on the primary replica for each partition

See Service Fabric Partition Aware Routing for more information on how to host NServiceBus with stateful services and to learn how to configure routing between service partitions and persist data in reliable collections.

NServiceBus provides persistence based on reliable collections for saga and outbox data. See Service Fabric persistence for details.

Guest executable

The guest executable option allows packaging and deployment of an existing endpoint into Service Fabric with minimal or no change at all. Service Fabric treats a guest executable as a stateless service.

This option can be used as an interim solution for the endpoints that eventually need to be converted to Service Fabric services but cannot be converted right away.

Hosting NServiceBus in a standalone cluster

Service Fabric can be deployed to run in any environment that contains a set of interconnected Windows Server machines. See the official documentation for details.

On Azure, Service Fabric can be hosted with Azure Service Fabric service.

Samples

Related Articles