Partilhar via


.NET Aspire Azure Service Bus integração

Inclui: integração de Hosting e integração de Client

Azure Service Bus é um agente de mensagens empresarial totalmente gerenciado com filas de mensagens e tópicos de publicação-assinatura. A integração .NET AspireAzure Service Bus permite-lhe ligar-se a instâncias Azure Service Bus de aplicações .NET.

Integração de hospedagem

A integração de hospedagem .NET.NET AspireAzure Service Bus modela os vários recursos do Service Bus como os seguintes tipos:

Para aceder esses tipos e APIs para expressá-los, adicione o 📦Aspire.Hosting.Azure.ServiceBus pacote NuGet no projeto da aplicação de host .

dotnet add package Aspire.Hosting.Azure.ServiceBus

Para obter mais informações, consulte dotnet add package ou Gerir dependências de pacotes em aplicações .NET.

Adicionar Azure Service Bus recurso

Em seu projeto de host de aplicativo, chame AddAzureServiceBus para adicionar e retornar um Azure Service Bus construtor de recursos.

var builder = DistributedApplication.CreateBuilder(args);

var serviceBus = builder.AddAzureServiceBus("messaging");

// After adding all resources, run the app...

Quando se adiciona um AzureServiceBusResource ao servidor da aplicação, ele expõe outras interfaces de programação de aplicações (APIs) úteis para adicionar filas e tópicos. Em outras palavras, você deve adicionar um AzureServiceBusResource antes de adicionar qualquer um dos outros recursos do Service Bus.

Importante

Quando você chama AddAzureServiceBus, ele chama implicitamente AddAzureProvisioning—que adiciona suporte para gerar recursos de Azure dinamicamente durante a inicialização do aplicativo. O aplicativo deve configurar a assinatura e o local apropriados. Para obter mais informações, consulte Configuration.

Geração de provisionamento Bicep

Se você é novo no Bicep, é uma linguagem específica do domínio para definir recursos Azure. Com .NET.NET Aspire, você não precisa escrever Bicep manualmente, em vez disso, as APIs de provisionamento geram Bicep para você. Ao publicares a tua aplicação, o Bicep gerado é exibido juntamente com o ficheiro de manifesto. Quando você adiciona um recurso Azure Service Bus, o seguinte Bicep é gerado:

@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location

param sku string = 'Standard'

param principalType string

param principalId string

resource service_bus 'Microsoft.ServiceBus/namespaces@2024-01-01' = {
  name: take('servicebus-${uniqueString(resourceGroup().id)}', 50)
  location: location
  properties: {
    disableLocalAuth: true
  }
  sku: {
    name: sku
  }
  tags: {
    'aspire-resource-name': 'service-bus'
  }
}

resource service_bus_AzureServiceBusDataOwner 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(service_bus.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419'))
  properties: {
    principalId: principalId
    roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419')
    principalType: principalType
  }
  scope: service_bus
}

output serviceBusEndpoint string = service_bus.properties.serviceBusEndpoint

O Bicep anterior é um módulo que provisiona um namespace Azure Service Bus com os seguintes padrões:

  • sku: A SKU do espaço de nomes do Service Bus. O padrão é Standard.
  • location: A localização do namespace do Service Bus. O padrão é o local do grupo de recursos.

Além do namespace do Service Bus, ele também provisiona uma função interna de controle de acesso baseado em função de Azure (RBACAzure) de Azure Service Bus Proprietário de Dados. A função é atribuída ao grupo de recursos do namespace do Service Bus. Para obter mais informações, consulte Azure Service Bus Proprietário de Dados.

Personalizar a infraestrutura de provisionamento

Todos os recursos .NET AspireAzure são subclasses do tipo AzureProvisioningResource. Esse tipo permite personalizar o Bicep gerado ao fornecer uma API fluente para configurar os recursos Azure, utilizando a API ConfigureInfrastructure<T>(IResourceBuilder<T>, Action<AzureResourceInfrastructure>). Por exemplo, pode-se configurar o SKU, a localização e muito mais. O exemplo a seguir demonstra como personalizar o recurso Azure Service Bus:

builder.AddAzureServiceBus("service-bus")
    .ConfigureInfrastructure(infra =>
    {
        var serviceBusNamespace = infra.GetProvisionableResources()
                                       .OfType<ServiceBusNamespace>()
                                       .Single();

        serviceBusNamespace.Sku = new ServiceBusSku
        {
            Tier = ServiceBusSkuTier.Premium
        };
        serviceBusNamespace.Tags.Add("ExampleKey", "Example value");
    });

O código anterior:

Há muito mais opções de configuração disponíveis para personalizar o recurso Azure Service Bus. Para obter mais informações, consulte Azure.Provisioning.ServiceBus. Para obter mais informações, consulte Azure. Personalização de provisionamento.

Conectar-se a um namespace de Azure Service Bus existente

Você pode ter um namespace Azure Service Bus existente ao qual deseja se conectar. Em vez de representar um novo recurso Azure Service Bus, você pode adicionar uma cadeia de conexão ao host do aplicativo. Para adicionar uma conexão a um namespace de Azure Service Bus existente, chame o método AddConnectionString:

var builder = DistributedApplication.CreateBuilder(args);

var serviceBus = builder.AddConnectionString("messaging");

builder.AddProject<Projects.WebApplication>("web")
       .WithReference(serviceBus);

// After adding all resources, run the app...

Observação

As cadeias de conexão são usadas para representar uma ampla gama de informações de conexão, incluindo conexões de banco de dados, agentes de mensagens, URIs de ponto de extremidade e outros serviços. Na nomenclatura .NET.NET Aspire, o termo "cadeia de conexão" é usado para representar qualquer tipo de informação de conexão.

A cadeia de conexão é configurada na configuração do host da aplicação, normalmente sob a seção Segredos do Utilizador, na secção ConnectionStrings. O host do aplicativo injeta essa cadeia de conexão como uma variável de ambiente em todos os recursos dependentes, por exemplo:

{
    "ConnectionStrings": {
        "messaging": "Endpoint=sb://{namespace}.servicebus.windows.net/;SharedAccessKeyName={key_name};SharedAccessKey={key_value};"
    }
}

O recurso dependente pode acessar a cadeia de conexão injetada chamando o método GetConnectionString e passando o nome da conexão como parâmetro, neste caso "messaging". A API GetConnectionString é uma abreviação de IConfiguration.GetSection("ConnectionStrings")[name].

Adicionar fila Azure Service Bus

Para adicionar uma fila de Azure Service Bus, chame o método AddServiceBusQueue no IResourceBuilder<AzureServiceBusResource>:

var builder = DistributedApplication.CreateBuilder(args);

var serviceBus = builder.AddAzureServiceBus("messaging");
serviceBus.AddServiceBusQueue("queue");

// After adding all resources, run the app...

Quando você chama AddServiceBusQueue(IResourceBuilder<AzureServiceBusResource>, String, String), ele configura seus recursos do Service Bus para ter uma fila chamada queue. A fila é criada no namespace do Service Bus representado pelo AzureServiceBusResource que você adicionou anteriormente. Para obter mais informações, veja Filas, tópicos e assinaturas no Azure Service Bus.

Adicionar o tópico Azure Service Bus e a subscrição

Para adicionar um tópico Azure Service Bus, chame o método AddServiceBusTopic no IResourceBuilder<AzureServiceBusResource>:

var builder = DistributedApplication.CreateBuilder(args);

var serviceBus = builder.AddAzureServiceBus("messaging");
serviceBus.AddServiceBusTopic("topic");

// After adding all resources, run the app...

Quando você chama AddServiceBusTopic(IResourceBuilder<AzureServiceBusResource>, String, String), ele configura seus recursos do Service Bus para ter um tópico chamado topic. O tópico é criado no namespace do Service Bus representado pelo AzureServiceBusResource que você adicionou anteriormente.

Para adicionar uma assinatura para o tópico, chame o método AddServiceBusSubscription no IResourceBuilder<AzureServiceBusTopicResource> e configure-o usando o método WithProperties:

using Aspire.Hosting.Azure;

var builder = DistributedApplication.CreateBuilder(args);

var serviceBus = builder.AddAzureServiceBus("messaging");
var topic = serviceBus.AddServiceBusTopic("topic");
topic.AddServiceBusSubscription("sub1")
     .WithProperties(subscription =>
     {
         subscription.MaxDeliveryCount = 10;
         subscription.Rules.Add(
             new AzureServiceBusRule("app-prop-filter-1")
             {
                 CorrelationFilter = new()
                 {
                     ContentType = "application/text",
                     CorrelationId = "id1",
                     Subject = "subject1",
                     MessageId = "msgid1",
                     ReplyTo = "someQueue",
                     ReplyToSessionId = "sessionId",
                     SessionId = "session1",
                     SendTo = "xyz"
                 }
             });
     });

// After adding all resources, run the app...

O código anterior não apenas adiciona um tópico e cria e configura uma assinatura chamada sub1 para o tópico. A assinatura tem uma contagem máxima de entrega de 10 e uma regra chamada app-prop-filter-1. A regra é um filtro de correlação que filtra mensagens com base nas propriedades ContentType, CorrelationId, Subject, MessageId, ReplyTo, ReplyToSessionId, SessionIde SendTo.

Para obter mais informações, consulte Filas, tópicos e assinaturas no Azure Service Bus.

Adicionar recurso Azure Service Bus do emulador

Para adicionar um recurso de emulador de Azure Service Bus, encadeie uma chamada num <IResourceBuilder<AzureServiceBusResource>> para a API RunAsEmulator:

var builder = DistributedApplication.CreateBuilder(args);

var serviceBus = builder.AddAzureServiceBus("messaging")
                        .RunAsEmulator();

// After adding all resources, run the app...

Quando você chama RunAsEmulator, ele configura os recursos do Service Bus para serem executados localmente usando um emulador. O emulador, neste caso, é o Azure Service Bus Emulator. O Azure Service Bus Emulator fornece um ambiente local gratuito para testar seus aplicativos Azure Service Bus e é um companheiro perfeito para a integração de hospedagem .NET AspireAzure. O emulador não está instalado, em vez disso, é acessível para .NET.NET Aspire como um contêiner. Quando você adiciona um contêiner ao host do aplicativo, como mostrado no exemplo anterior com a imagem mcr.microsoft.com/azure-messaging/servicebus-emulator (e a imagem mcr.microsoft.com/azure-sql-edge acompanhante), ele cria e inicia o contêiner quando o host do aplicativo é iniciado. Para obter mais informações, consulte Ciclo de vida do recurso de contêiner.

Configurar o contêiner do emulador do Service Bus

Há várias configurações disponíveis para recursos de contêiner, por exemplo, você pode configurar as portas do contêiner ou fornecer uma configuração de JSON holística que substitui tudo.

Configurar a porta do host do contêiner do emulador do Service Bus

Por padrão, o contêiner do emulador do Service Bus, quando configurado pelo .NET.NET Aspire, expõe os seguintes pontos de extremidade:

Ponto final Imagem Porto de contentores Porta do host
emulator mcr.microsoft.com/azure-messaging/servicebus-emulator 5672 dinâmico
tcp mcr.microsoft.com/azure-sql-edge 1433 dinâmico

A porta em que ele está a escutar é dinâmica por padrão. Quando o contêiner é iniciado, a porta é mapeada para uma porta aleatória na máquina host. Para configurar a porta do ponto de extremidade, encadeie chamadas no construtor de recursos de contêiner fornecido pelo método RunAsEmulator e, em seguida, o WithHostPort(IResourceBuilder<AzureServiceBusEmulatorResource>, Nullable<Int32>) conforme mostrado no exemplo a seguir:

var builder = DistributedApplication.CreateBuilder(args);

var serviceBus = builder.AddAzureServiceBus("messaging").RunAsEmulator(
                         emulator =>
                         {
                             emulator.WithHostPort(7777);
                         });

// After adding all resources, run the app...

O código anterior configura o endpoint existente emulator do contentor do emulador do Service Bus para ouvir na porta 7777. A porta do contentor do emulador do Service Bus é mapeada para a porta do host, conforme mostrado na tabela a seguir:

Nome do ponto final Cartografia de portos (container:host)
emulator 5672:7777
Configurar a configuração do contentor do emulador do Service Bus JSON

O contêiner do emulador do Service Bus é executado com um arquivo config.json padrão. Você pode modificar este arquivo por completo ou atualizar a configuração JSON com uma representação JsonNode da configuração.

Para fornecer um arquivo de configuração de JSON personalizado, chame o método WithConfigurationFile(IResourceBuilder<AzureServiceBusEmulatorResource>, String):

var builder = DistributedApplication.CreateBuilder(args);

var serviceBus = builder.AddAzureServiceBus("messaging").RunAsEmulator(
                         emulator =>
                         {
                             emulator.WithConfigurationFile(
                                 path: "./messaging/custom-config.json");
                         });

O código anterior configura o contêiner do emulador do Service Bus para usar um arquivo de configuração de JSON personalizado localizado em ./messaging/custom-config.json. Para substituir propriedades específicas na configuração padrão, chame o método WithConfiguration(IResourceBuilder<AzureServiceBusEmulatorResource>, Action<JsonNode>):

var builder = DistributedApplication.CreateBuilder(args);

var serviceBus = builder.AddAzureServiceBus("messaging").RunAsEmulator(
                         emulator =>
                         {
                             emulator.WithConfiguration(
                                 (JsonNode configuration) =>
                                 {
                                     var userConfig = configuration["UserConfig"];
                                     var ns = userConfig["Namespaces"][0];
                                     var firstQueue = ns["Queues"][0];
                                     var properties = firstQueue["Properties"];
                                     
                                     properties["MaxDeliveryCount"] = 5;
                                     properties["RequiresDuplicateDetection"] = true;
                                     properties["DefaultMessageTimeToLive"] = "PT2H";
                                 });
                         });

// After adding all resources, run the app...

O código anterior recupera o nó UserConfig da configuração padrão. Em seguida, atualiza as propriedades da primeira fila para definir o MaxDeliveryCount como 5, RequiresDuplicateDetection para truee DefaultMessageTimeToLive para 2 hours.

Verificações de estado da integração de hospedagem

A integração de hospedagem Azure Service Bus adiciona automaticamente uma verificação de integridade para o recurso do Service Bus. A verificação de integridade verifica se o Service Bus está em execução e se uma conexão pode ser estabelecida com ele.

A integração de hospedagem depende do 📦 AspNetCore.HealthChecks.AzureServiceBus pacote NuGet.

Client Integração

Para começar com a integração do cliente .NET AspireAzure Service Bus, instale o pacote NuGet 📦Aspire.Azure.Messaging.ServiceBus no projeto consumidor do cliente, ou seja, o projeto da aplicação que utiliza o cliente do Service Bus. A integração do cliente do Service Bus registra uma instância de ServiceBusClient que você pode usar para interagir com o Service Bus.

dotnet add package Aspire.Azure.Messaging.ServiceBus

Adicionar cliente do Service Bus

No arquivo de Program.cs do seu projeto cliente-consumidor, chame o método de extensão AddAzureServiceBusClient em qualquer IHostApplicationBuilder para registrar um ServiceBusClient para uso através do contêiner de injeção de dependência. O método usa um parâmetro de nome de conexão.

builder.AddAzureServiceBusClient(connectionName: "messaging");

")

O parâmetro connectionName deve corresponder ao nome usado ao adicionar o recurso do Service Bus no projeto de host do aplicativo. Em outras palavras, quando você chama AddAzureServiceBus e fornece um nome de messaging esse mesmo nome deve ser usado ao chamar AddAzureServiceBusClient. Para obter mais informações, consulte Adicionar Azure Service Bus recurso.

Em seguida, você pode recuperar a instância ServiceBusClient usando a injeção de dependência. Por exemplo, para recuperar a conexão de um serviço de exemplo:

public class ExampleService(ServiceBusClient client)
{
    // Use client...
}

Para obter mais informações sobre injeção de dependência, consulte .NET injeção de dependência.

Adicionar cliente do Service Bus com chave

Pode haver situações em que você queira registrar várias instâncias de ServiceBusClient com nomes de conexão diferentes. Para registrar clientes do Service Bus com chave, chame o método AddKeyedAzureServiceBusClient:

builder.AddKeyedAzureServiceBusClient(name: "mainBus");
builder.AddKeyedAzureServiceBusClient(name: "loggingBus");

Importante

Ao usar serviços com chave, espera-se que o recurso do Service Bus tenha configurado dois barramentos nomeados, um para o mainBus e outro para o loggingBus.

Em seguida, é possível recuperar as instâncias ServiceBusClient usando a injeção de dependência. Por exemplo, para recuperar a conexão de um serviço de exemplo:

public class ExampleService(
    [FromKeyedServices("mainBus")] ServiceBusClient mainBusClient,
    [FromKeyedServices("loggingBus")] ServiceBusClient loggingBusClient)
{
    // Use clients...
}

Para obter mais informações sobre serviços identificados por chave, consulte a seção .NET sobre injeção de dependência: Serviços identificados por chave.

Configuração

A integração .NET AspireAzure Service Bus fornece várias opções para configurar a conexão com base nos requisitos e convenções do seu projeto.

Usar uma string de conexão

Ao usar uma cadeia de conexão da seção de configuração de ConnectionStrings, você pode fornecer o nome da cadeia de conexão ao chamar o método AddAzureServiceBusClient:

builder.AddAzureServiceBusClient("messaging");

Em seguida, a cadeia de conexão é recuperada da seção de configuração ConnectionStrings:

{
  "ConnectionStrings": {
    "messaging": "Endpoint=sb://{namespace}.servicebus.windows.net/;SharedAccessKeyName={keyName};SharedAccessKey={key};"
  }
}

Para obter mais informações sobre como formatar essa cadeia de conexão, consulte a documentação ConnectionString.

Usar provedores de configuração

A integração .NET AspireAzure Service Bus suporta Microsoft.Extensions.Configuration. Ele carrega o AzureMessagingServiceBusSettings a partir da configuração usando a chave Aspire:Azure:Messaging:ServiceBus. O trecho a seguir é um exemplo de um arquivo de appsettings.json que configura algumas das opções:

{
  "Aspire": {
    "Azure": {
      "Messaging": {
        "ServiceBus": {
          "ConnectionString": "Endpoint=sb://{namespace}.servicebus.windows.net/;SharedAccessKeyName={keyName};SharedAccessKey={key};",
          "DisableTracing": false
        }
      }
    }
  }
}

Para o esquema completo de integração do cliente do Service Bus JSON, veja Aspire.Azure.Messaging.ServiceBus/ConfigurationSchema.json.

Usar delegados integrados

Além disso, podes passar o delegado Action<AzureMessagingServiceBusSettings> configureSettings para configurar algumas ou todas as opções diretamente, por exemplo, para desativar o rastreamento a partir do código.

builder.AddAzureServiceBusClient(
    "messaging",
    static settings => settings.DisableTracing = true);

Você também pode configurar o Azure.Messaging.ServiceBus.ServiceBusClientOptions usando o parâmetro Action<ServiceBusClientOptions> configureClientOptions opcional do método AddAzureServiceBusClient. Por exemplo, para definir o sufixo ServiceBusClientOptions.Identifier do cabeçalho user-agent para todas as solicitações feitas por este cliente:

builder.AddAzureServiceBusClient(
    "messaging",
    configureClientOptions:
        clientOptions => clientOptions.Identifier = "myapp");

Client verificações de saúde de integração

Por padrão, as integrações .NET.NET Aspire habilitam verificações de integridade para todos os serviços. Para obter mais informações, consulte .NET.NET Aspire visão geral das integrações.

A integração .NET AspireAzure Service Bus:

  • Adiciona a verificação de integridade quando AzureMessagingServiceBusSettings.DisableTracing é false, que tenta se conectar ao Service Bus.
  • Integra-se com o endpoint HTTP /health, que especifica que todas as verificações de integridade registadas devem passar para que a aplicação seja considerada pronta para aceitar tráfego.

Observabilidade e telemetria

.NET .NET Aspire integrações configuram automaticamente as configurações de Logging, Trace e Metrics, que às vezes são conhecidas como os pilares da observabilidade. Para obter mais informações sobre observabilidade e telemetria de integração, consulte Visão geral de integrações .NET.NET Aspire. Dependendo do serviço de suporte, algumas integrações podem suportar apenas alguns desses recursos. Por exemplo, algumas integrações suportam registro em log e rastreamento, mas não métricas. Os recursos de telemetria também podem ser desativados usando as técnicas apresentadas na seção de configuração .

Registo

A integração .NET AspireAzure Service Bus usa as seguintes categorias de log:

  • Azure.Core
  • Azure.Identity
  • Azure-Messaging-ServiceBus

Além de obter Azure Service Bus diagnósticos de solicitação para solicitações com falha, você pode configurar limites de latência para determinar quais diagnósticos de solicitação de Azure Service Bus bem-sucedidos serão registrados. Os valores padrão são 100 ms para operações pontuais e 500 ms para operações sem ponto.

builder.AddAzureServiceBusClient(
    "messaging",
    configureClientOptions:
        clientOptions => {
            clientOptions.ServiceBusClientTelemetryOptions = new()
            {
                ServiceBusThresholdOptions = new()
                {
                    PointOperationLatencyThreshold = TimeSpan.FromMilliseconds(50),
                    NonPointOperationLatencyThreshold = TimeSpan.FromMilliseconds(300)
                }
            };
        });

Rastreio

A integração .NET AspireAzure Service Bus emitirá as seguintes atividades de rastreio utilizando OpenTelemetry:

  • Message
  • ServiceBusSender.Send
  • ServiceBusSender.Schedule
  • ServiceBusSender.Cancel
  • ServiceBusReceiver.Receive
  • ServiceBusReceiver.ReceiveDeferred
  • ServiceBusReceiver.Peek
  • ServiceBusReceiver.Abandon
  • ServiceBusReceiver.Complete
  • ServiceBusReceiver.DeadLetter
  • ServiceBusReceiver.Defer
  • ServiceBusReceiver.RenewMessageLock
  • ServiceBusSessionReceiver.RenewSessionLock
  • ServiceBusSessionReceiver.GetSessionState
  • ServiceBusSessionReceiver.SetSessionState
  • ServiceBusProcessor.ProcessMessage
  • ServiceBusSessionProcessor.ProcessSessionMessage
  • ServiceBusRuleManager.CreateRule
  • ServiceBusRuleManager.DeleteRule
  • ServiceBusRuleManager.GetRules

Azure Service Bus rastreamento está atualmente em visualização, portanto, você deve definir o comutador experimental para garantir que os vestígios sejam emitidos.

AppContext.SetSwitch("Azure.Experimental.EnableActivitySource", true);

Para obter mais informações, consulte Azure Service Bus: Rastreamento distribuído e correlação por meio de mensagens do Service Bus.

Métricas

A integração de .NET AspireAzure Service Bus atualmente não oferece suporte a métricas por padrão devido a limitações com o Azure SDK.

Ver também