Getting Started
Architecture
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Samples

Azure Functions with Service Bus (Isolated Worker)

The isolated worker model is a newer hosting option for Azure Functions. Running out-of-process decouples the function code from the Azure Functions runtime. For further information about the isolated worker, refer to the Microsoft documentation.

Usage

NServiceBus supports the isolated worker hosting model via the NServiceBus.AzureFunctions.Worker.ServiceBus NuGet package. The following configuration enables NServiceBus:

[assembly: NServiceBusTriggerFunction("WorkerDemoEndpoint")]

public class Program
{
    public static Task Main()
    {
        var host = new HostBuilder()
            .ConfigureFunctionsWorkerDefaults()
            .UseNServiceBus()
            .Build();

        return host.RunAsync();
    }
}

The Azure Service Bus trigger is automatically generated by the NServiceBusTriggerFunction attribute which will forward incoming messages to the appropriate message handlers.

Should customization of the Azure Service Bus trigger be required, it can be manually declared instead of relying on the auto-generated trigger. See the article on custom Azure Functions triggers for more information.

Dispatching outside a message handler

To send/publish messages outside a message handler, inject IFunctionEndpoint into custom triggers. This snippet shows an HTTP trigger sending a message via NServiceBus:

public class HttpTrigger
{
    readonly IFunctionEndpoint functionEndpoint;

    public HttpTrigger(IFunctionEndpoint functionEndpoint)
    {
        this.functionEndpoint = functionEndpoint;
    }

    [Function("HttpSender")]
    public async Task<HttpResponseData> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestData req,
        FunctionContext executionContext)
    {
        await functionEndpoint.Send(new TriggerMessage(), executionContext);

        return req.CreateResponse(HttpStatusCode.OK);
    }
}

Configuration

ServiceBusTriggeredEndpointConfiguration loads certain configuration values from the Azure Function host environment in the following order:

  1. IConfiguration
  2. Environment variables
KeyValueNotes
AzureWebJobsServiceBusConnection string for the Azure ServiceBus namespace to connect toThis value is required for ServiceBusTriggerAttribute.
NSERVICEBUS_LICENSEThe NServiceBus licenseCan also be provided via serviceBusTriggeredEndpointConfig.AdvancedConfiguration.License(...).
ENDPOINT_NAMEThe name of the NServiceBus endpoint to hostOptional. By default, the endpoint name is derived from the NServiceBusTriggerFunction attribute.
WEBSITE_SITE_NAMEThe name of the Azure Function app. Provided when hosting the function in Azure.Optional. Used to set the NServiceBus host identifier. Local machine name is used if not set.

For local development, use the local.settings.json file. In Azure, specify a Function setting using the environment variable as the key.

{
  "IsEncrypted": false,
  "Values": {
    ...
    "NSERVICEBUS_LICENSE": "<?xml version=\"1.0\" encoding=\"utf-8\"?><license id=\"1222e1d1-2222-4a46-b1c6-943c442ca710\" expiration=\"2113-11-30T00:00:00.0000000\" type=\"Standard\" LicenseType=\"Standard\" LicenseVersion=\"4.0\" MaxMessageThroughputPerSecond=\"Max\" WorkerThreads=\"Max\" AllowedNumberOfWorkerNodes=\"Max\">. . .</license>"
  }
}

Transactions

Unlike the in-process hosting model, the isolated worker model does not support using TransportTransactionMode.SendsAtomicWithReceive. TransportTransactionMode.ReceiveOnly is the default option.

Custom diagnostics

NServiceBus startup diagnostics are disabled by default when using Azure Functions. Diagnostics can be written to the logs via the LogDiagnostics option:

public static Task Main()
{
    var host = new HostBuilder()
        .ConfigureFunctionsWorkerDefaults()
        .UseNServiceBus(configuration =>
        {
            configuration.LogDiagnostics();
        })
        .Build();

    return host.RunAsync();
}

Diagnostics data will be written with logger identification StartupDiagnostics with log level Informational.

Error queue

By default, repeatedly failing messages are sent to the error queue. The error queue can be configured or disabled completely to let the native Azure Service Bus dead-lettering configuration handle failures:

public static Task Main()
{
    var host = new HostBuilder()
        .ConfigureFunctionsWorkerDefaults()
        .UseNServiceBus(configuration =>
        {
            // Change the error queue name:
            configuration.AdvancedConfiguration.SendFailedMessagesTo("my-custom-error-queue");

            // Or disable the error queue to let ASB native dead-lettering handle repeated failures:
            configuration.DoNotSendMessagesToErrorQueue();
        })
        .Build();

    return host.RunAsync();
}

Known constraints and limitations

The configuration API exposes NServiceBus transport configuration options via the configuration.Transport property to allow customization. However, not all options will be applicable to execution within Azure Functions.

Use the configuration.Routing property to configure transport routing.

Preparing the Azure Service Bus namespace

Function endpoints can create their own queues or other infrastructure in the Azure Service Bus namespace by using the configuration.AdvancedConfiguration.EnableInstallers() method.

To manually provision the entities in the namespace for the Function endpoint use the asb-transport command line (CLI) tool.

Creating the endpoint queue

asb-transport endpoint create <queue name>

See the operation scripting documentation for the asb-transport endpoint create command for more details.

Subscribing to events

asb-transport endpoint subscribe <queue name> <eventtype>

See the operational scripting documentation for the asb-transport endpoint subscribe command for more details.

Samples

Related Articles