← ASP.NET Core: aplicações, contratos e operação
10 / 10 · 60 MIN

Entrega, proxies e recuperação

Distingue o artefacto publicado do processo ativo e preserva as fronteiras de confiança, identidade e recuperação através da publicação.

Ficheiros, processo e aceitação

dotnet publish produz ficheiros para executar a aplicação, mas não demonstra que um servidor os recebeu ou que o processo os carregou. Uma sonda básica pode continuar a responder através da versão anterior. Distingue distribuição, ativação e aceitação funcional.

Relaciona um identificador de build confiável com o artefacto esperado e observa o comportamento exigido através da rota relevante. A supervisão de arranque e reinício do processo também precisa de configuração no ambiente de destino.

A fronteira do proxy

Quando o proxy termina TLS e usa HTTP para o backend, a aplicação precisa de metadata confiável para conhecer o esquema original. ForwardedHeaders seleciona os campos processados; KnownProxies identifica remetentes esperados e ForwardLimit delimita quantas entradas são consumidas.

Um cabeçalho enviado diretamente por um cliente não ganha confiança por conter um endereço interno. Mantém também controlos de rede que evitem acesso direto não pretendido e audita os valores predefinidos de confiança.

Ordem e esquema original

UseForwardedHeaders deve preceder os consumidores que decidem pelo esquema ou pela origem. Se HTTPS redirection observa sempre HTTP após terminação TLS, pode redirecionar um cliente que já usa HTTPS e criar um ciclo. Processar XForwardedProto aceite antes dessa decisão corrige a premissa.

Aumentar o número de redirecionamentos do cliente ou aceitar metadata de qualquer origem não trata corretamente a causa. A configuração tem de corresponder ao proxy e à cadeia realmente presentes.

Caminho público e caminho interno

Confirma se o proxy conserva ou remove o prefixo público. Com /portal/version intacto, UsePathBase("/portal") separa PathBase e Path antes do matching, pelo que UseRouting deve ocorrer depois. Se o proxy já entrega /version, a aplicação pode precisar de repor PathBase para gerar links públicos corretos, sem remover novamente um segmento da rota.

A mesma configuração aplicada a topologias diferentes pode produzir 404 ou links sem o prefixo esperado.

Paragem e trabalho incerto

StopAsync pertence à paragem graciosa. Um crash pode impedir essa chamada, pelo que o único registo de progresso não deve ser guardado apenas aí. O token de paragem e o timeout orientam a cooperação do serviço, mas não desfazem uma escrita remota.

Se uma resposta se perde depois de um efeito, reiniciar pode repetir trabalho já confirmado. Usa estado durável e identidade de operação para reconciliar o resultado segundo o contrato; não concluas ausência de efeito apenas a partir de cancelamento.

Identidade entre instâncias

Data Protection usa chaves para proteger dados como cookies da aplicação. Com key rings locais independentes, uma instância pode não conseguir desproteger o cookie emitido por outra. Antes de culpar a palavra-passe, confronta a mudança de nó com o erro observado.

Configura partilha controlada de chaves e os restantes parâmetros de compatibilidade exigidos. Afinidade pode manter pedidos no mesmo nó, mas não demonstra que o cookie continuará válido quando esse nó deixar de servir.

Recuperar o serviço observável

Uma reversão de ficheiros pode restaurar uma versão de código sem restaurar os dados, os efeitos remotos ou a configuração anterior. Define os critérios de aceitação e de recuperação antes da mudança: versão ativa, caminhos públicos, identidade, dependências e resultado funcional.

No cenário em que a nova pasta existe mas o processo continua antigo, 200 em /health é insuficiente. O diagnóstico deve ligar cada evidência ao componente e à versão que a produziram, preservando os limites do que foi observado.

// ASP.NET Core 10 Program.cs reading example.
// Topology premise: one trusted edge at 192.0.2.10 (documentation address).
// The edge overwrites X-Forwarded-For/Proto and preserves /portal in Path.
// Production must use its real proxy address and restrict direct ingress.
using System.Net;
using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
                               ForwardedHeaders.XForwardedProto;
    options.ForwardLimit = 1;
    options.KnownProxies.Add(IPAddress.Parse("192.0.2.10"));
    // Framework loopback trust defaults remain; audit them for your topology.
});
builder.Services.AddHttpsRedirection(options => options.HttpsPort = 443);
var app = builder.Build();
app.UseForwardedHeaders();
app.UseHttpsRedirection();
app.UsePathBase("/portal");
app.UseRouting();
app.MapGet("/version", () => Results.Ok(new { build = "training-r2" }));
app.Run();
NA PRÁTICA

Interpreta o exemplo com um só proxy e /portal preservado. Um pedido público /portal/version chega com esse caminho; UsePathBase separa a base antes de UseRouting. XForwardedProto permite interpretar HTTPS original quando o remetente é aceite.

O IP é ilustrativo e os valores loopback predefinidos continuam presentes. A constante training-r2 é apenas um identificador de exemplo; não prova distribuição, hash do artefacto ou comportamento de todas as instâncias.

Armadilhas comuns

Copiar ficheiros não ativa necessariamente a versão. Cabeçalhos forwarded arbitrários não são prova da origem. Remover duas vezes um prefixo quebra rotas.

Paragem graciosa não garante execução perante crash. Afinidade com um nó não equivale a partilha de chaves entre todos os nós.

Tópicos relacionados: Alojamento, middleware e percurso do pedido · Saúde, observabilidade e diagnóstico · Autenticação e autorização

Leva esta ideia contigo

Aceita a mudança pela versão efetivamente ativa, pelo caminho público correto e pelo resultado funcional. Mantém a recuperação independente de callbacks que podem não ocorrer e preserva a configuração de confiança entre instâncias.

Criar conta

Referência: Publish artifact boundary · ASP.NET Core 10.0 / .NET 10 / C# 14