Partilhar via


.NET .NET Aspire padrões de serviço

Neste artigo, você aprenderá sobre o projeto de padrões de serviço .NET.NET Aspire, um conjunto de métodos de extensão que:

Os aplicativos nativos da nuvem geralmente exigem configurações extensas para garantir que funcionem em diferentes ambientes de forma confiável e segura. .NET Aspire fornece muitos métodos e ferramentas auxiliares para simplificar o gerenciamento de configurações para OpenTelemetry, verificações de integridade, variáveis de ambiente e muito mais.

Explore o projeto de padrões de serviço

Quando você Inscrever-se em .NET.NET Aspire de orquestração ou criar um novo projeto .NET.NET Aspire, o YourAppName.ServiceDefaults.csproj projeto é adicionado à sua solução. Por exemplo, ao criar uma API, você chama o método AddServiceDefaults no arquivo Program.cs de seus aplicativos:

builder.AddServiceDefaults();

O método AddServiceDefaults lida com as seguintes tarefas:

  • Configura OpenTelemetry métricas e rastreamento.
  • Adiciona pontos de extremidade de verificação de integridade padrão.
  • Adiciona a funcionalidade de descoberta de serviço.
  • Configura HttpClient para trabalhar com descoberta de serviço.

Para obter mais informações, consulte Métodos de extensão fornecidos para obter detalhes sobre o método AddServiceDefaults.

Importante

O projeto .NET.NET Aspire service defaults foi projetado especificamente para compartilhar o arquivo Extensions.cs e sua funcionalidade. Não inclua outras funcionalidades ou modelos compartilhados neste projeto. Use um projeto de biblioteca de classe compartilhada convencional para esses fins.

Características do projeto

O projeto YourAppName.ServiceDefaults é uma biblioteca .NET 9.0 que contém o seguinte XML:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <IsAspireSharedProject>true</IsAspireSharedProject>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />

    <PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="9.0.0" />
    <PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="9.0.0" />
    <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.10.0" />
    <PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.10.0" />
    <PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.10.1" />
    <PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.10.0" />
    <PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.10.0" />
  </ItemGroup>

</Project>

O modelo de projeto padrão de serviço impõe uma dependência FrameworkReference de Microsoft.AspNetCore.App.

Dica

Se você não quiser depender de Microsoft.AspNetCore.App, você pode criar um projeto de padrão de serviço personalizado. Para obter mais informações, consulte Padrões de serviço personalizados.

A propriedade IsAspireSharedProject está definida como true, o que indica que este projeto é um projeto compartilhado. O .NET Aspire tooling usa este projeto como referência para outros projetos adicionados a uma solução .NET Aspire. Quando você inscreve o novo projeto para orquestração, ele faz referência automática ao YourAppName.ServiceDefaults projeto e atualiza o arquivo Program.cs para chamar o método AddServiceDefaults.

Métodos de extensão fornecidos

O YourAppName.ServiceDefaults projeto expõe um único arquivo Extensions.cs que contém vários métodos de extensão opinativos:

  • AddServiceDefaults: Adiciona a funcionalidade de padrões de serviço.
  • ConfigureOpenTelemetry: Configura OpenTelemetry métricas e rastreamento.
  • AddDefaultHealthChecks: Adiciona pontos de extremidade de verificação de integridade padrão.
  • MapDefaultEndpoints: Mapeia o ponto de extremidade de verificações de integridade para /health e o ponto de extremidade de vivacidade para /alive.

Adicionar funcionalidade de padrões de serviço

O método AddServiceDefaults define configurações padrão com a seguinte funcionalidade opinativa:

public static IHostApplicationBuilder AddServiceDefaults(
    this IHostApplicationBuilder builder)
{
    builder.ConfigureOpenTelemetry();

    builder.AddDefaultHealthChecks();

    builder.Services.AddServiceDiscovery();

    builder.Services.ConfigureHttpClientDefaults(http =>
    {
        // Turn on resilience by default
        http.AddStandardResilienceHandler();

        // Turn on service discovery by default
        http.AddServiceDiscovery();
    });

    // Uncomment the following to restrict the allowed schemes for service discovery.
    // builder.Services.Configure<ServiceDiscoveryOptions>(options =>
    // {
    //     options.AllowedSchemes = ["https"];
    // });

    return builder;
}

O código anterior:

  • Configura OpenTelemetry métricas e rastreamento, chamando o método ConfigureOpenTelemetry.
  • Adiciona pontos de extremidade de verificação de integridade padrão, chamando o método AddDefaultHealthChecks.
  • Adiciona descoberta de serviço funcionalidade, chamando o método AddServiceDiscovery.
  • Configura HttpClient padrões, chamando o método ConfigureHttpClientDefaults — que se baseia em Crie aplicativos HTTP resilientes: Principais padrões de desenvolvimento:
    • Adiciona o manipulador de resiliência HTTP padrão, chamando o método AddStandardResilienceHandler.
    • Especifica que o IHttpClientBuilder deve usar a descoberta de serviço, chamando o método UseServiceDiscovery.
  • Retorna a instância IHostApplicationBuilder para permitir o encadeamento de métodos.

OpenTelemetry configuração

A telemetria é uma parte crítica de qualquer aplicativo nativo da nuvem. .NET Aspire fornece um conjunto de padrões opinativos para OpenTelemetry, que são configurados com o método ConfigureOpenTelemetry:

public static IHostApplicationBuilder ConfigureOpenTelemetry(
    this IHostApplicationBuilder builder)
{
    builder.Logging.AddOpenTelemetry(logging =>
    {
        logging.IncludeFormattedMessage = true;
        logging.IncludeScopes = true;
    });

    builder.Services.AddOpenTelemetry()
        .WithMetrics(metrics =>
        {
            metrics.AddAspNetCoreInstrumentation()
                .AddHttpClientInstrumentation()
                .AddRuntimeInstrumentation();
        })
        .WithTracing(tracing =>
        {
            if (builder.Environment.IsDevelopment())
            {
                // We want to view all traces in development
                tracing.SetSampler(new AlwaysOnSampler());
            }

            tracing.AddAspNetCoreInstrumentation()
                // Uncomment the following line to enable gRPC instrumentation 
                // (requires the OpenTelemetry.Instrumentation.GrpcNetClient package)
                //.AddGrpcClientInstrumentation()
                .AddHttpClientInstrumentation();
        });

    builder.AddOpenTelemetryExporters();

    return builder;
}

O método ConfigureOpenTelemetry:

  • Adiciona .NET.NET Aspire telemetria registro em log para incluir mensagens formatadas e escopos.
  • Adiciona OpenTelemetry métricas e rastreamento que incluem:
    • Métricas de instrumentação em tempo de execução.
    • ASP.NET Core métricas de instrumentação.
    • Métricas de instrumentação HttpClient.
    • Em um ambiente de desenvolvimento, o AlwaysOnSampler é usado para exibir todos os rastreamentos.
    • Detalhes de rastreamento para instrumentação ASP.NET Core, gRPC e HTTP.
  • Adiciona OpenTelemetry exportadores, chamando AddOpenTelemetryExporters.

O método AddOpenTelemetryExporters é definido de forma privada da seguinte forma:

private static IHostApplicationBuilder AddOpenTelemetryExporters(
    this IHostApplicationBuilder builder)
{
    var useOtlpExporter = !string.IsNullOrWhiteSpace(
        builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);

    if (useOtlpExporter)
    {
        builder.Services.Configure<OpenTelemetryLoggerOptions>(
            logging => logging.AddOtlpExporter());
        builder.Services.ConfigureOpenTelemetryMeterProvider(
            metrics => metrics.AddOtlpExporter());
        builder.Services.ConfigureOpenTelemetryTracerProvider(
            tracing => tracing.AddOtlpExporter());
    }

    // Uncomment the following lines to enable the Prometheus exporter
    // (requires the OpenTelemetry.Exporter.Prometheus.AspNetCore package)
    // builder.Services.AddOpenTelemetry()
    //    .WithMetrics(metrics => metrics.AddPrometheusExporter());

    // Uncomment the following lines to enable the Azure Monitor exporter 
    // (requires the Azure.Monitor.OpenTelemetry.AspNetCore package)
    //if (!string.IsNullOrEmpty(
    //    builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]))
    //{
    //    builder.Services.AddOpenTelemetry()
    //       .UseAzureMonitor();
    //}

    return builder;
}

O método AddOpenTelemetryExporters adiciona OpenTelemetry exportadores com base nas seguintes condições:

  • Se a variável de ambiente OTEL_EXPORTER_OTLP_ENDPOINT for definida, o OpenTelemetry exportador será adicionado.
  • Opcionalmente, os consumidores de .NET Aspire padrões de serviço podem descomentar algum código para habilitar o exportador Prometheus ou o exportador do Azure Monitor.

Para obter mais informações, consulte .NET.NET Aspire telemetria.

Configuração de verificações de integridade

As verificações de integridade são usadas por várias ferramentas e sistemas para avaliar a prontidão do seu aplicativo. .NET .NET Aspire fornece um conjunto de padrões opinativos para verificações de integridade, que são configurados com o método AddDefaultHealthChecks:

public static IHostApplicationBuilder AddDefaultHealthChecks(
    this IHostApplicationBuilder builder)
{
    builder.Services.AddHealthChecks()
        // Add a default liveness check to ensure app is responsive
        .AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]);

    return builder;
}

O método AddDefaultHealthChecks adiciona uma verificação de vivacidade padrão para garantir que o aplicativo seja responsivo. A chamada para AddHealthChecks registra o HealthCheckService. Para obter mais informações, consulte .NET.NET Aspire verificações de integridade.

Configuração de verificações de integridade do aplicativo Web

Para expor verificações de integridade em um aplicativo Web, .NET.NET Aspire determina automaticamente o tipo de projeto que está sendo referenciado na solução e adiciona a chamada apropriada a MapDefaultEndpoints:

public static WebApplication MapDefaultEndpoints(this WebApplication app)
{
    // Uncomment the following line to enable the Prometheus endpoint 
    // (requires the OpenTelemetry.Exporter.Prometheus.AspNetCore package)
    // app.MapPrometheusScrapingEndpoint();

    // Adding health checks endpoints to applications in non-development 
    // environments has security implications.
    // See https://aka.ms/dotnet/aspire/healthchecks for details before 
    // enabling these endpoints in non-development environments.
    if (app.Environment.IsDevelopment())
    {
        // All health checks must pass for app to be considered ready to 
        // accept traffic after starting
        app.MapHealthChecks("/health");

        // Only health checks tagged with the "live" tag must pass for 
        // app to be considered alive
        app.MapHealthChecks("/alive", new HealthCheckOptions
        {
            Predicate = r => r.Tags.Contains("live")
        });
    }

    return app;
}

O método MapDefaultEndpoints:

  • Permite que os consumidores descomentem, opcionalmente, algum código para ativar o ponto de extremidade Prometheus.
  • Mapeia o ponto de extremidade de verificações de integridade para /health.
  • Mapeia o ponto de extremidade de vivacidade para /alive rota onde a marca de verificação de integridade contém live.

Para obter mais informações, consulte .NET.NET Aspire verificações de integridade.

Padrões de serviço personalizado

Se a configuração de serviço padrão fornecida pelo modelo de projeto não for suficiente para suas necessidades, você terá a opção de criar seu próprio projeto de padrão de serviço. Isso é especialmente útil quando seu projeto consumidor, como um projeto Worker ou um projeto WinForms, não pode ou não quer ter uma dependência FrameworkReference de Microsoft.AspNetCore.App.

Para fazer isso, crie um novo projeto de biblioteca de classes .NET 9.0 e adicione as dependências necessárias ao arquivo de projeto, considere o seguinte exemplo:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Library</OutputType>
    <TargetFramework>net9.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting" />
    <PackageReference Include="Microsoft.Extensions.ServiceDiscovery" />
    <PackageReference Include="Microsoft.Extensions.Http.Resilience" />
    <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" />
    <PackageReference Include="OpenTelemetry.Extensions.Hosting" />
    <PackageReference Include="OpenTelemetry.Instrumentation.Http" />
    <PackageReference Include="OpenTelemetry.Instrumentation.Runtime" />
  </ItemGroup>
</Project>

Em seguida, crie uma classe de extensões que contenha os métodos necessários para configurar os padrões do aplicativo:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using OpenTelemetry.Logs;
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;

namespace Microsoft.Extensions.Hosting;

public static class AppDefaultsExtensions
{
    public static IHostApplicationBuilder AddAppDefaults(
        this IHostApplicationBuilder builder)
    {
        builder.ConfigureAppOpenTelemetry();

        builder.Services.AddServiceDiscovery();

        builder.Services.ConfigureHttpClientDefaults(http =>
        {
            // Turn on resilience by default
            http.AddStandardResilienceHandler();

            // Turn on service discovery by default
            http.AddServiceDiscovery();
        });

        return builder;
    }

    public static IHostApplicationBuilder ConfigureAppOpenTelemetry(
        this IHostApplicationBuilder builder)
    {
        builder.Logging.AddOpenTelemetry(logging =>
        {
            logging.IncludeFormattedMessage = true;
            logging.IncludeScopes = true;
        });

        builder.Services.AddOpenTelemetry()
            .WithMetrics(static metrics =>
            {
                metrics.AddRuntimeInstrumentation();
            })
            .WithTracing(tracing =>
            {
                if (builder.Environment.IsDevelopment())
                {
                    // We want to view all traces in development
                    tracing.SetSampler(new AlwaysOnSampler());
                }

                tracing.AddGrpcClientInstrumentation()
                       .AddHttpClientInstrumentation();
            });

        builder.AddOpenTelemetryExporters();

        return builder;
    }

    private static IHostApplicationBuilder AddOpenTelemetryExporters(
        this IHostApplicationBuilder builder)
    {
        var useOtlpExporter =
            !string.IsNullOrWhiteSpace(
                builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);

        if (useOtlpExporter)
        {
            builder.Services.Configure<OpenTelemetryLoggerOptions>(
                logging => logging.AddOtlpExporter());
            builder.Services.ConfigureOpenTelemetryMeterProvider(
                metrics => metrics.AddOtlpExporter());
            builder.Services.ConfigureOpenTelemetryTracerProvider(
                tracing => tracing.AddOtlpExporter());
        }

        return builder;
    }
}

Este é apenas um exemplo, e você pode personalizar a classe AppDefaultsExtensions para atender às suas necessidades específicas.

Próximos passos

Este código é derivado do modelo .NET.NET Aspire Starter Application e destina-se como um ponto de partida. Você é livre para modificar este código como achar necessário para atender às suas necessidades. É importante saber que o projeto padrão de serviço e sua funcionalidade são aplicados automaticamente a todos os recursos do projeto em uma solução .NET.NET Aspire.