.NET에 대한 신뢰할 수 있는 웹앱 패턴 - 패턴 적용

Azure App Service
Azure Front Door
Azure Cache for Redis
.NET

이 문서에서는 신뢰할 수 있는 웹앱 패턴을 적용하는 방법을 보여 줍니다. 신뢰할 수 있는 웹앱 패턴은 클라우드로 마이그레이션할 때 웹앱을 수정(다시 배치)하는 방법을 정의하는 일련의 원칙 및 구현 기술 입니다. 클라우드에서 성공하기 위해 수행해야 하는 최소한의 코드 업데이트에 중점을 둡니다.

이 지침의 적용을 용이하게 하기 위해 배포할 수 있는 신뢰할 수 있는 웹앱 패턴의 참조 구현 이 있습니다.

참조 구현의 아키텍처를 보여 주는 다이어그램참조 구현의 아키텍처입니다. 이 아키텍처의 Visio 파일을 다운로드합니다.

다음 지침에서는 참조 구현을 전체 예제로 사용합니다. 신뢰할 수 있는 웹앱 패턴을 적용하려면 잘 설계된 프레임워크의 핵심 요소에 맞게 조정된 다음 권장 사항을 따릅니다.

안정성

안정성은 애플리케이션이 고객에 대한 약속을 충족할 수 있도록 합니다. 자세한 내용은 디자인 검토 검사 안정성 목록을 참조하세요. 신뢰할 수 있는 웹앱 패턴은 안정성을 향상시키기 위해 코드 수준에서 두 가지 주요 디자인 패턴인 재시도 패턴과 회로 차단기 패턴을 도입합니다.

다시 시도 패턴 사용

다시 시도 패턴일시적인 오류라는 임시 서비스 중단을 해결하며, 일반적으로 몇 초 내에 해결됩니다. 이러한 오류는 종종 클라우드 환경의 서비스 제한, 동적 부하 분산 및 네트워크 문제로 인해 발생합니다. 다시 시도 패턴을 구현하려면 실패한 요청을 다시 보내서 오류를 양보하기 전에 구성 가능한 지연 및 시도를 허용합니다.

재시도 패턴을 사용하는 애플리케이션은 효율성을 높이기 위해 Azure의 SDK(클라이언트 소프트웨어 개발 키트) 및 서비스별 재시도 메커니즘을 통합해야 합니다. 이 패턴이 없는 애플리케이션은 다음 지침을 사용하여 채택해야 합니다.

먼저 Azure 서비스 및 클라이언트 SDK 사용해 보기

대부분의 Azure 서비스 및 클라이언트 SDK에는 기본 제공 재시도 메커니즘이 있습니다. 구현을 신속하게 처리하려면 Azure 서비스에 대한 기본 제공 재시도 메커니즘을 사용해야 합니다.

예: 참조 구현은 Entity Framework Core연결 복원력을 사용하여 요청에서 재시도 패턴을 Azure SQL Database적용합니다(다음 코드 참조).

services.AddDbContextPool<ConcertDataContext>(options => options.UseSqlServer(sqlDatabaseConnectionString,
    sqlServerOptionsAction: sqlOptions =>
    {
        sqlOptions.EnableRetryOnFailure(
        maxRetryCount: 5,
        maxRetryDelay: TimeSpan.FromSeconds(3),
        errorNumbersToAdd: null);
    }));

클라이언트 라이브러리가 재시도를 지원하지 않는 경우 Polly 라이브러리 사용

Azure 서비스가 아니거나 재시도 패턴을 기본적으로 지원하지 않는 종속성을 호출해야 할 수 있습니다. 이 경우 Polly 라이브러리를 사용하여 재시도 패턴을 구현해야 합니다. Polly 는 .NET 복원력 및 일시적인 오류 처리 라이브러리입니다. 이를 통해 유창한 API를 사용하여 애플리케이션의 중앙 위치에서 동작을 설명할 수 있습니다.

예제: 참조 구현에서는 Polly를 사용하여 ASP.NET Core 종속성 주입을 설정합니다. Polly는 코드가 개체를 호출 IConcertSearchService 하는 개체를 생성할 때마다 재시도 패턴을 적용합니다. Polly 프레임워크에서 해당 동작을 정책이라고 합니다. 코드는 메서드에서 GetRetryPolicy 이 정책을 추출하고 GetRetryPolicy 프런트 엔드 웹앱이 Web API Concert Search 서비스를 호출할 때마다 다시 시도 패턴을 적용합니다(다음 코드 참조).

private void AddConcertSearchService(IServiceCollection services)
{
    var baseUri = Configuration["App:RelecloudApi:BaseUri"];
    if (string.IsNullOrWhiteSpace(baseUri))
    {
        services.AddScoped<IConcertSearchService, MockConcertSearchService>();
    }
    else
    {
        services.AddHttpClient<IConcertSearchService, RelecloudApiConcertSearchService>(httpClient =>
        {
            httpClient.BaseAddress = new Uri(baseUri);
            httpClient.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/json");
            httpClient.DefaultRequestHeaders.Add(HeaderNames.UserAgent, "Relecloud.Web");
        })
        .AddPolicyHandler(GetRetryPolicy())
        .AddPolicyHandler(GetCircuitBreakerPolicy());
    }
}

private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
    var delay = Backoff.DecorrelatedJitterBackoffV2(TimeSpan.FromMilliseconds(500), retryCount: 3);
    return HttpPolicyExtensions
      .HandleTransientHttpError()
      .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
      .WaitAndRetryAsync(delay);
}

인스턴스에 RelecloudApiConcertSearchService 대한 정책 처리기는 모든 요청에 대해 재시도 패턴을 API에 적용합니다. 논리를 HandleTransientHttpError 사용하여 안전하게 다시 시도할 수 있는 HTTP 요청을 검색한 다음 구성에 따라 요청을 다시 시도합니다. 여기에는 오류가 발생할 경우 API에 대한 트래픽의 잠재적 버스트를 원활하게 하기 위한 일부 임의성이 포함됩니다.

회로 차단기 패턴 사용

재시도 및 회로 차단기 패턴을 페어링하면 일시적 오류와 관련이 없는 서비스 중단을 처리하는 애플리케이션의 기능이 확장됩니다. 회로 차단기 패턴애플리케이션이 응답하지 않는 서비스에 계속 액세스하지 못하도록 합니다. 회로 차단기 패턴은 애플리케이션을 해제하고 CPU 주기를 낭비하지 않으므로 애플리케이션이 최종 사용자의 성능 무결성을 유지합니다.

예: 참조 구현은 메서드에 GetCircuitBreakerPolicy 회로 차단기 패턴을 추가합니다(다음 코드 참조).

private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
{
    return HttpPolicyExtensions
        .HandleTransientHttpError()
        .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
        .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
}

코드에서 인스턴스에 RelecloudApiConcertSearchService 대한 정책 처리기는 API에 대한 모든 요청에 회로 차단기 패턴을 적용합니다. 이 논리는 HandleTransientHttpError HTTP 요청을 검색하여 안전하게 다시 시도할 수 있지만 지정된 기간 동안 집계 오류 수를 제한합니다.

보안

우수한 보안은 중요한 데이터 및 시스템에 대한 고의적인 공격과 악용을 방어합니다. 자세한 내용은 보안에 대한 디자인 검토 검사 목록을 참조하세요. 신뢰할 수 있는 웹앱 패턴은 관리 ID를 사용하여 ID 중심 보안을 구현합니다. 프라이빗 엔드포인트, 웹 애플리케이션 방화벽 및 웹앱에 대한 제한된 액세스는 안전한 수신을 제공합니다.

최소 권한 적용

보안 및 효율성을 보장하려면 사용자(사용자 ID) 및 Azure 서비스(워크로드 ID)에게 필요한 권한만 부여합니다.

사용자 ID에 권한 할당

겹치지 않고 모든 사용자 작업을 포함하는 역할 집합을 정의해야 하는 애플리케이션의 요구 사항을 평가합니다. 각 사용자를 가장 적절한 역할에 매핑합니다. 업무에 필요한 것만 액세스할 수 있는지 확인합니다.

워크로드 ID에 권한 할당

데이터베이스의 CRUD 작업 또는 비밀 액세스와 같이 작업에 중요한 권한만 부여합니다. 워크로드 ID 권한은 영구적이므로 워크로드 ID에 대한 Just-In-Time 또는 단기 권한을 제공할 수 없습니다.

  • RBAC(역할 기반 액세스 제어)를 선호합니다. 항상 Azure RBAC사용하여 권한을 할당합니다. 정밀한 제어를 제공하여 액세스가 감사 가능하고 세분화되어 있는지 확인합니다. Azure RBAC를 사용하여 서비스에서 의도한 기능을 수행하는 데 필요한 권한만 부여합니다.

  • Azure 서비스 수준 액세스 제어를 보완합니다. Azure RBAC가 특정 시나리오를 다루지 않는 경우 Azure 서비스 수준 액세스 정책을 보완합니다.

사용자 인증 및 권한 부여 구성

인증 및 권한 부여는 웹 애플리케이션 보안의 중요한 측면입니다. 인증 은 사용자의 ID를 확인하는 프로세스입니다. 권한 부여 는 사용자가 애플리케이션 내에서 수행할 수 있는 작업을 지정합니다. 목표는 보안 상태를 약화시키지 않고 인증 및 권한 부여를 구현하는 것입니다. 이 목표를 달성하려면 Azure 애플리케이션 플랫폼(Azure 앱 Service) 및 ID 공급자(Microsoft Entra ID)의 기능을 사용해야 합니다.

사용자 인증 구성

플랫폼의 기능을 통해 사용자 인증을 사용하도록 설정하여 웹앱을 보호합니다. Azure 앱 Service는 Microsoft Entra ID와 같은 ID 공급자와의 인증을 지원하여 코드에서 인증 워크로드를 오프로드합니다.

서비스 인증 및 권한 부여 구성

사용자 환경의 서비스에 필요한 기능을 수행할 수 있는 권한이 있도록 서비스 인증 및 권한 부여를 구성합니다. Microsoft Entra ID의 관리 ID를 사용하여 서비스 ID의 생성 및 관리를 자동화하여 수동 자격 증명 관리를 제거합니다. 관리 ID를 사용하면 웹앱이 Azure Key Vault 및 데이터베이스와 같은 Azure 서비스에 안전하게 액세스할 수 있습니다. 또한 Azure 앱 Service에 배포하기 위한 CI/CD 파이프라인 통합을 용이하게 합니다. 그러나 하이브리드 배포 또는 레거시 시스템과 같은 시나리오에서는 온-프레미스 인증 솔루션을 계속 사용하여 마이그레이션을 간소화합니다. 시스템이 최신 ID 관리 접근 방식을 사용할 준비가 되면 관리 ID로 전환합니다. 자세한 내용은 관리 ID 모니터링을 참조 하세요.

DefaultAzureCredential을 사용하여 코드 설정

클라우드에서 로컬 개발 및 관리 ID에 대한 자격 증명을 제공하는 데 사용합니다 DefaultAzureCredential . DefaultAzureCredentialTokenCredential OAuth 토큰 획득을 생성합니다. 대부분의 Azure SDK 시나리오 및 Microsoft 클라이언트 라이브러리를 처리합니다. 올바른 ID를 사용하기 위해 애플리케이션의 환경을 검색하고 필요에 따라 액세스 토큰을 요청합니다. DefaultAzureCredential Azure 배포 애플리케이션에 대한 인증을 간소화합니다. 자세한 내용은 DefaultAzureCredential을 참조 하세요.

예: 참조 구현은 시작 중에 클래스를 사용하여 DefaultAzureCredential 웹 API와 Key Vault 간에 관리 ID를 사용할 수 있도록 합니다(다음 코드 참조).

builder.Configuration.AddAzureAppConfiguration(options =>
{
     options
        .Connect(new Uri(builder.Configuration["Api:AppConfig:Uri"]), new DefaultAzureCredential())
        .ConfigureKeyVault(kv =>
        {
            // Some of the values coming from Azure App Configuration are stored Key Vault. Use
            // the managed identity of this host for the authentication.
            kv.SetCredential(new DefaultAzureCredential());
        });
});

코드로 인프라를 사용하여 관리 ID 만들기

Bicep 템플릿을 사용하여 관리 ID를 지원하도록 Azure 인프라를 만들고 구성해야 합니다. 관리 ID는 비밀 또는 암호를 사용하지 않으므로 무결성을 보장하기 위해 Key Vault 또는 비밀 회전 전략이 필요하지 않습니다. App Configuration Service에 연결 문자열 저장할 수 있습니다.

예: 참조 구현은 Bicep 템플릿을 사용하여 (1) 관리 ID를 만들고, (2) ID를 웹앱과 연결하고, (3) SQL 데이터베이스에 액세스할 수 있는 ID 권한을 부여합니다. 연결 문자열 인수는 Authentication Microsoft 클라이언트 라이브러리에 관리 ID로 연결하도록 지시합니다(다음 코드 참조).

    Server=tcp:my-sql-server.database.windows.net,1433;Initial Catalog=my-sql-database;Authentication=Active Directory Default

자세한 내용은 .NET App Service에서 SQL 데이터베이스에 커넥트 참조하세요.

중앙 비밀 저장소를 사용하여 비밀 관리

애플리케이션을 클라우드로 이동하는 경우 Azure Key Vault를 사용하여 이러한 모든 비밀을 안전하게 저장합니다. 이 중앙 집중식 리포지토리는 관리 ID를 지원하지 않는 서비스에 대한 보안 스토리지, 키 회전, 액세스 감사 및 모니터링을 제공합니다. 애플리케이션 구성의 경우 Azure 앱 구성을 사용하는 것이 좋습니다.

예: 참조 구현은 Key Vault에 다음 비밀을 저장합니다. (1) PostgreSQL 데이터베이스 사용자 이름 및 암호, (2) Redis Cache 암호 및 (3) MSAL(Microsoft 인증 라이브러리) 구현과 연결된 Microsoft Entra ID의 클라이언트 암호입니다.

HTTP 요청 흐름에 Key Vault를 배치하지 마세요.

각 HTTP 요청 중에 대신 애플리케이션 시작 시 Key Vault에서 비밀을 로드합니다. Key Vault는 배포 중에 중요한 데이터를 안전하게 저장하고 검색하기 위한 것입니다. HTTP 요청 내의 고주파 액세스는 Key Vault의 처리량 기능을 초과할 수 있으므로 요청 제한 사항 및 HTTP 상태 코드 429 오류가 발생합니다. 자세한 내용은 Key Vault 트랜잭션 제한을 참조 하세요.

한 가지 방법을 사용하여 Key Vault의 비밀에 액세스

Key Vault의 비밀에 액세스하도록 웹앱을 구성하는 경우 두 가지 기본 옵션이 있습니다.

  • App Service 앱 설정: App Service의 앱 설정을 사용하여 비밀을 환경 변수직접 삽입합니다.

  • 직접 비밀 참조: 애플리케이션 코드 내에서 비밀을 직접 참조합니다. 앱이 Key Vault와 통신할 수 있도록 Java 애플리케이션과 같은 application.properties 애플리케이션의 속성 파일에 특정 참조를 추가합니다.

이러한 방법 중 하나를 선택하고 단순성을 위해 이를 고수하고 불필요한 복잡성을 방지하는 것이 중요합니다.

임시 액세스 방법 선호

임시 사용 권한을 사용하여 무단 액세스 및 위반으로부터 보호합니다. 임시 액세스를 위해 SAS(공유 액세스 서명)를 사용합니다. 임시 액세스 권한을 부여할 때 사용자 위임 SAS를 사용하여 보안을 최대화합니다. Microsoft Entra 자격 증명을 사용하고 스토리지 계정 키가 필요하지 않은 유일한 SAS입니다.

프라이빗 엔드포인트 사용

지원되는 모든 Azure 서비스에 대해 모든 프로덕션 환경에서 프라이빗 엔드포인트를 사용합니다. 프라이빗 엔드포인트는 Azure 가상 네트워크와 Azure 서비스의 리소스 간에 프라이빗 연결을 제공합니다. 기본적으로 대부분의 Azure 서비스에 대한 통신은 공용 인터넷을 교차합니다. 프라이빗 엔드포인트에는 코드 변경, 앱 구성 또는 연결 문자열 필요하지 않습니다. 자세한 내용은 엔드포인트 보안에 대한 프라이빗 엔드포인트모범 사례를 만드는 방법을 참조하세요.

예: Azure 앱 구성, Azure SQL Database, Azure Cache for Redis, Azure Storage, Azure 앱 Service 및 Key Vault는 프라이빗 엔드포인트를 사용합니다.

웹 애플리케이션 방화벽 사용 및 인바운드 인터넷 트래픽 제한

웹앱에 대한 모든 인바운드 인터넷 트래픽은 일반적인 웹 악용으로부터 보호하기 위해 웹 애플리케이션 방화벽을 통과해야 합니다. 모든 인바운드 인터넷 트래픽이 공용 부하 분산 장치(있는 경우) 및 웹 애플리케이션 방화벽을 통과하도록 합니다.

예: 참조 구현은 Front Door 및 Azure 웹 애플리케이션 방화벽을 통해 모든 인바운드 인터넷 트래픽을 강제 적용합니다. 프로덕션 환경에서 원래 HTTP 호스트 이름을 유지합니다.

데이터베이스 보안 구성

관리 데이터베이스에 대한 주 서버 수준 액세스 권한은 권한 있는 작업을 수행할 수 있는 권한을 부여합니다. 권한 있는 작업에는 데이터베이스 만들기 및 삭제, 테이블 스키마 수정 또는 사용자 권한 변경이 포함됩니다. 개발자는 데이터베이스를 기본 문제를 해결하기 위해 관리자 수준의 액세스 권한이 필요한 경우가 많습니다.

  • 영구 관리자 권한은 사용하지 않습니다. 권한 있는 작업을 수행하려면 개발자에게 Just-In-Time 액세스 권한만 부여해야 합니다. Just-In-Time 액세스를 통해 사용자는 권한 있는 작업을 수행할 수 있는 임시 권한을 받습니다.

  • 애플리케이션에 상승된 권한을 부여하지 마세요. 애플리케이션 ID에 대한 관리자 수준 액세스 권한을 부여해서는 안 됩니다. 데이터베이스에 대한 애플리케이션에 대한 최소 권한 액세스를 구성해야 합니다. 버그 및 보안 위반의 폭발 반경을 제한합니다.

비용 최적화

비용 최적화는 불필요한 비용과 관리 오버헤드를 줄이는 방법을 찾는 것입니다. 자세한 내용은 디자인 검토 검사 비용 최적화 목록을 참조하세요. 신뢰할 수 있는 웹앱 패턴은 비용 최적화 웹앱에 대한 권한 부여 기술, 자동 크기 조정 및 효율적인 리소스 사용을 구현합니다.

각 환경에 대한 리소스 권한 부여

Azure 서비스의 다양한 성능 계층을 이해하고 각 환경의 요구에 적합한 SKU만 사용합니다. 프로덕션 환경에는 SLA(서비스 수준 계약), 기능 및 프로덕션에 필요한 규모를 충족하는 SKU가 필요합니다. 비프로덕션 환경은 일반적으로 동일한 기능이 필요하지 않습니다. 추가 절감을 위해 컴퓨팅에 대한 Azure 개발/테스트 가격 책정 옵션, Azure ReservationsAzure 절감 계획을 고려합니다.

예: 참조 구현은 Bicep 매개 변수를 사용하여 리소스 배포 구성을 트리거합니다. 이러한 매개 변수 중 하나는 배포할 SKU(리소스 계층)를 나타냅니다. 웹앱은 프로덕션 환경에 더 성능이 높고 비용이 많이 드는 SKU와 비프로덕션 환경에 더 저렴한 SKU를 사용합니다(다음 코드 참조).

var redisCacheSkuName = isProd ? 'Standard' : 'Basic'
var redisCacheFamilyName = isProd ? 'C' : 'C'
var redisCacheCapacity = isProd ? 1 : 0

자동 크기 조정 사용

자동 크기 조정은 프로덕션 환경에 대한 수평 크기 조정을 자동화합니다. 성능 메트릭에 따라 자동 크기 조정 애플리케이션의 크기 조정 조건을 이해하지 못하는 경우 CPU 사용률 성능 트리거는 좋은 시작점입니다. 웹 애플리케이션의 동작에 맞게 크기 조정 트리거(CPU, RAM, 네트워크 및 디스크)를 구성하고 조정해야 합니다. 수요가 자주 변경되는 경우를 충족하기 위해 수직으로 크기를 조정하지 마세요. 비용 효율성이 떨어집니다. 자세한 내용은 Microsoft Azure의 Azure 앱 Service자동 크기 조정에서 크기 조정을 참조하세요.

예: 참조 구현은 Bicep 템플릿에서 다음 구성을 사용합니다. Azure 앱 서비스에 대한 자동 크기 조정 규칙을 만듭니다. 규칙은 최대 10개의 인스턴스로 확장되며 기본값은 하나의 인스턴스로 설정됩니다. 스케일 인 및 스케일 아웃을 위한 트리거로 CPU 사용량을 사용합니다. 웹앱 호스팅 플랫폼은 85%의 CPU 사용량으로 확장되고 60%로 확장됩니다. 100%에 가까운 백분율이 아닌 85%의 스케일 아웃 설정은 고정 세션으로 인한 누적된 사용자 트래픽으로부터 보호하는 버퍼를 제공합니다. 또한 최대 CPU 사용량을 방지하기 위해 일찍 크기를 조정하여 높은 트래픽 버스트로부터 보호합니다. 이러한 자동 크기 조정 규칙은 범용이 아닙니다(다음 코드 참조).

resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (autoScaleSettings != null) { 
  name: '${name}-autoscale' 
  location: location 
  tags: tags 
  properties: { 
    targetResourceUri: appServicePlan.id 
    enabled: true 
    profiles: [ 
      { 
        name: 'Auto created scale condition' 
        capacity: { 
          minimum: string(zoneRedundant ? 3 : autoScaleSettings!.minCapacity) 
          maximum: string(autoScaleSettings!.maxCapacity) 
          default: string(zoneRedundant ? 3 : autoScaleSettings!.minCapacity) 
        } 
        rules: [ 
          ... 
        ] 
      } 
    ] 
  } 
}

리소스를 효율적으로 사용

  • 공유 서비스를 사용합니다. 특정 리소스를 중앙 집중화하고 공유하면 비용 최적화 및 관리 오버헤드가 줄어듭니다. 공유 네트워크 리소스를 허브 가상 네트워크에 배치합니다.

    예: 참조 구현은 허브 가상 네트워크에 Azure Firewall, Azure Bastion 및 Key Vault를 배치합니다.

  • 사용하지 않는 환경을 삭제합니다. 비용을 최적화하기 위해 몇 시간 후 또는 휴일 동안 비프로덕션 환경을 삭제합니다. 인프라를 코드로 사용하여 Azure 리소스 및 전체 환경을 삭제할 수 있습니다. Bicep 템플릿에서 삭제하려는 리소스의 선언을 제거합니다. 변경 내용을 적용하기 전에 미리 보려면 what-if 작업을 사용합니다. 나중에 필요한 데이터를 백업합니다. 삭제하는 리소스에 대한 종속성을 이해합니다. 종속성이 있는 경우 해당 리소스도 업데이트하거나 제거해야 할 수 있습니다. 자세한 내용은 Bicep 배포 what-if 작업을 참조하세요.

  • 공동 배치 기능 여분의 용량이 있는 경우 단일 Azure 리소스에 애플리케이션 리소스 및 기능을 공동 배치합니다. 예를 들어 여러 웹앱이 단일 서버(App Service 계획)를 사용하거나 단일 캐시가 여러 데이터 형식을 지원할 수 있습니다.

    예: 참조 구현은 프런트 엔드(카트 및 MSAL 토큰 저장) 및 백 엔드(예정된 Concerts 데이터 보유) 웹앱 모두에서 세션 관리에 단일 Azure Cache for Redis 인스턴스를 사용합니다. 가장 작은 Redis SKU를 선택하여 필요한 용량 이상을 제공하며 비용을 제어하기 위해 여러 데이터 형식을 사용하여 효율적으로 활용합니다.

운영 우수성

운영 우수성은 애플리케이션을 배포하고 프로덕션에서 계속 실행하는 운영 프로세스를 다룹니다. 자세한 내용은 운영 우수성대한 디자인 검토 검사 목록을 참조하세요. 신뢰할 수 있는 웹앱 패턴은 인프라 배포 및 모니터링을 위한 코드로 인프라를 구현합니다.

배포 자동화

CI/CD 파이프라인을 사용하여 소스 제어에서 프로덕션으로 변경 내용을 배포합니다. Azure DevOps를 사용하는 경우 Azure Pipelines를 사용해야 합니다. GitHub를 사용하는 경우 GitHub 작업을 사용합니다. Azure 지원s ARM 템플릿(JSON), Bicep 및 Terraform이며 모든 Azure 리소스에 대한 템플릿이 있습니다. 자세한 내용은 다음을 참조하세요.Bicep, Azure Resource Manager 및 Terraform 템플릿 및반복 가능한 인프라.

예제: 참조 구현은 Azure Dev CLI 및 인프라를 코드(Bicep 템플릿)로 사용하여 Azure 리소스를 만들고 구성을 설정하며 필요한 리소스를 배포합니다.

모니터링 구성

웹앱을 모니터링하려면 애플리케이션 코드, 인프라(런타임) 및 플랫폼(Azure 리소스)에서 메트릭과 로그를 수집하고 분석합니다. 아키텍처의 모든 Azure 리소스에 대한 진단 설정을 추가합니다. 각 Azure 서비스에는 캡처할 수 있는 다른 로그 및 메트릭 집합이 있습니다. 자세한 내용은 플랫폼 모니터링 및 App Service 모니터링을 참조하세요.

기준 메트릭 모니터링

Azure 애플리케이션 Insights를 사용하여 요청 처리량, 평균 요청 기간, 오류 및 종속성 모니터링과 같은 기준 메트릭을 추적합니다. NuGet 패키지 Microsoft.ApplicationInsights.AspNetCore 에서 원격 AddApplicationInsightsTelemetry 분석 수집을 사용하도록 설정합니다. 자세한 내용은 .NET에서 Application Insights 원격 분석종속성 주입 사용을 참조하세요.

예제: 참조 구현은 코드를 사용하여 Application Insights에서 기준 메트릭을 구성합니다(다음 코드 참조).

public void ConfigureServices(IServiceCollection services)
{
   ...
   services.AddApplicationInsightsTelemetry(Configuration["App:Api:ApplicationInsights:ConnectionString"]);
   ...
}

필요에 따라 사용자 지정 원격 분석 만들기

Application Insights를 사용하여 사용자 지정 원격 분석을 수집하여 웹앱 사용자를 더 잘 이해할 수 있습니다. 클래스의 인스턴스를 TelemetryClient 만들고 메서드를 TelemetryClient 사용하여 올바른 메트릭을 만듭니다. 쿼리를 Azure 대시보드 위젯으로 전환합니다.

예: 참조 구현은 운영 팀이 웹앱이 트랜잭션을 성공적으로 완료하고 있음을 식별하는 데 도움이 되는 메트릭을 추가합니다. 요청 수 또는 CPU 사용량을 측정하는 것이 아니라 고객이 주문을 할 수 있는지 여부를 모니터링하여 웹앱이 온라인 상태인지 확인합니다. 참조 구현은 종속성 주입 및 메서드를 통해 카트 활동과 TrackEvent 관련된 이벤트에 대한 원격 분석을 수집하는 데 사용됩니다TelemetryClient. 원격 분석은 사용자가 추가, 제거 및 구매하는 티켓을 추적합니다(다음 코드 참조).

  • AddToCart 는 사용자가 카트에 특정 티켓(ConcertID)을 추가하는 횟수를 계산합니다.
  • RemoveFromCart 사용자가 카트에서 제거하는 티켓을 기록합니다.
  • CheckoutCart 는 사용자가 티켓을 구매할 때마다 이벤트를 기록합니다.

this.telemetryClient.TrackEvent 은 카트에 추가된 티켓을 계산합니다. 이벤트 이름(AddToCart)을 제공하고 및 (다음 코드 참조)가 있는 concertIdcount사전을 지정합니다.

this.telemetryClient.TrackEvent("AddToCart", new Dictionary<string, string> {
    { "ConcertId", concertId.ToString() },
    { "Count", count.ToString() }
});

자세한 내용은 다음을 참조하세요.

로그 기반 메트릭 수집

로그 기반 메트릭을 추적하여 필수 애플리케이션 상태 및 메트릭에 대한 가시성을 높입니다. Application Insights에서 KQL(Kusto 쿼리 언어) 쿼리를 사용하여 데이터를 찾고 구성할 수 있습니다. 자세한 내용은 Azure 애플리케이션 Insights 로그 기반 메트릭 및 Application Insights의 로그 기반 및 사전 집계 메트릭을 참조하세요.

플랫폼 진단 사용

Azure의 진단 설정을 사용하면 수집하려는 플랫폼 로그 및 메트릭을 지정하고 저장할 위치를 지정할 수 있습니다. 플랫폼 로그는 진단 및 감사 정보를 제공하는 기본 제공 로그입니다. 대부분의 Azure 서비스에 대해 플랫폼 진단 사용하도록 설정할 수 있지만 각 서비스는 자체 로그 범주를 정의합니다. 다른 Azure 서비스에는 선택할 로그 범주가 있습니다.

  • 지원되는 모든 서비스에 대해 진단 사용하도록 설정합니다. Azure 서비스는 플랫폼 로그를 자동으로 만들지만 서비스는 자동으로 저장하지 않습니다. 각 서비스에 대해 진단 설정을 사용하도록 설정해야 하며, 진단 지원하는 모든 Azure 서비스에 대해 사용하도록 설정해야 합니다.

  • 애플리케이션 로그와 동일한 대상으로 진단 보냅니다. 진단 사용하도록 설정하면 수집하려는 로그와 보낼 위치를 선택합니다. 두 데이터 세트의 상관 관계를 지정할 수 있도록 플랫폼 로그를 애플리케이션 로그와 동일한 대상으로 보내야 합니다.

성능 효율성

성능 효율성은 사용자가 배치된 요구 사항을 효율적인 방식으로 충족하기 위해 워크로드의 크기를 조정할 수 있는 기능입니다. 자세한 내용은 성능 효율성에 대한 디자인 검토 검사 목록을 참조하세요. 신뢰할 수 있는 웹앱 패턴은 캐시 배제 패턴을 사용하여 요청이 많은 데이터의 대기 시간을 최소화합니다.

캐시 배제 패턴 사용

캐시 배제 패턴은 메모리 내 데이터 관리를 개선하는 캐싱 전략입니다. 이 패턴은 데이터 요청을 처리하고 캐시와 영구 스토리지(예: 데이터베이스) 간의 일관성을 보장하는 책임을 애플리케이션에 할당합니다. 웹앱이 데이터 요청을 받으면 먼저 캐시를 검색합니다. 데이터가 누락된 경우 데이터베이스에서 검색하고 요청에 응답하며 그에 따라 캐시를 업데이트합니다. 이 방법은 응답 시간을 단축하고 처리량을 향상시키고 더 많은 크기 조정의 필요성을 줄입니다. 또한 기본 데이터 저장소의 부하를 줄이고 중단 위험을 최소화하여 서비스 가용성을 강화합니다.

예: 참조 구현은 티켓 판매에 중요한 예정된 콘서트에 대한 정보와 같은 중요한 데이터를 캐싱하여 애플리케이션 효율성을 향상시킵니다. 메모리 내 항목 스토리지에 ASP.NET Core의 분산 메모리 캐시를 사용합니다. 애플리케이션은 특정 연결 문자열 찾으면 Azure Cache for Redis를 자동으로 사용합니다. 또한 설치를 간소화하고 비용과 복잡성을 줄이기 위해 Redis가 없는 로컬 개발 환경을 지원합니다. 메서드(AddAzureCacheForRedis)는 Azure Cache for Redis를 사용하도록 애플리케이션을 구성합니다(다음 코드 참조).

private void AddAzureCacheForRedis(IServiceCollection services)
{
    if (!string.IsNullOrWhiteSpace(Configuration["App:RedisCache:ConnectionString"]))
    {
        services.AddStackExchangeRedisCache(options =>
        {
            options.Configuration = Configuration["App:RedisCache:ConnectionString"];
        });
    }
    else
    {
        services.AddDistributedMemoryCache();
    }
}

자세한 내용은 ASP.NET CoreAddDistributedMemoryCache 메서드의 분산 캐싱을 참조하세요.

필요한 데이터 캐시

가장 자주 액세스하는 데이터에 대한 캐싱 우선 순위를 지정합니다. 사용자 참여 및 시스템 성능을 구동하는 주요 데이터 요소를 식별합니다. 캐시 배제 패턴의 효율성을 최적화하기 위해 이러한 영역에 대한 캐싱 전략을 구현하여 대기 시간 및 데이터베이스 부하를 크게 줄입니다. Azure Monitor를 사용하여 데이터베이스의 CPU, 메모리 및 스토리지를 추적합니다. 이러한 메트릭은 더 작은 데이터베이스 SKU를 사용할 수 있는지 여부를 결정하는 데 도움이 됩니다.

예: 참조 구현은 예정된 콘서트를 지원하는 데이터를 캐시합니다. 예정된 콘서트 페이지는 SQL Database에 대한 가장 많은 쿼리를 만들고 각 방문에 대해 일관된 출력을 생성합니다. Cache-Aside 패턴은 데이터베이스의 부하를 줄이기 위해 이 페이지에 대한 첫 번째 요청 이후 데이터를 캐시합니다. 다음 코드는 이 메서드를 GetUpcomingConcertsAsync 사용하여 SQL Database에서 Redis 캐시로 데이터를 끌어온다. 이 메서드는 캐시를 최신 콘서트로 채웁니다. 메서드는 시간별로 필터링하고, 데이터를 정렬하고, 컨트롤러에 데이터를 반환하여 결과를 표시합니다(다음 코드 참조).

public async Task<ICollection<Concert>> GetUpcomingConcertsAsync(int count)
{
    IList<Concert>? concerts;
    var concertsJson = await this.cache.GetStringAsync(CacheKeys.UpcomingConcerts);
    if (concertsJson != null)
    {
        // There is cached data. Deserialize the JSON data.
        concerts = JsonSerializer.Deserialize<IList<Concert>>(concertsJson);
    }
    else
    {
        // There's nothing in the cache. Retrieve data from the repository and cache it for one hour.
        concerts = await this.database.Concerts.AsNoTracking()
            .Where(c => c.StartTime > DateTimeOffset.UtcNow && c.IsVisible)
            .OrderBy(c => c.StartTime)
            .Take(count)
            .ToListAsync();
        concertsJson = JsonSerializer.Serialize(concerts);
        var cacheOptions = new DistributedCacheEntryOptions {
            AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
        };
        await this.cache.SetStringAsync(CacheKeys.UpcomingConcerts, concertsJson, cacheOptions);
    }
    return concerts ?? new List<Concert>();
}

캐시 데이터를 최신 상태로 유지

최신 데이터베이스 변경 내용과 동기화하도록 일반 캐시 업데이트를 예약합니다. 데이터 변동성 및 사용자 요구에 따라 최적의 새로 고침 속도를 결정합니다. 이렇게 하면 애플리케이션이 Cache-Aside 패턴을 사용하여 빠른 액세스 및 현재 정보를 모두 제공할 수 있습니다.

예: 참조 구현은 1시간 동안만 데이터를 캐시합니다. 데이터가 변경되면 캐시 키를 지우는 프로세스가 있습니다. 이 메서드는 CreateConcertAsync 캐시 키를 지웁니다(다음 코드 참조).

public async Task<CreateResult> CreateConcertAsync(Concert newConcert)
{
    database.Add(newConcert);
    await this.database.SaveChangesAsync();
    this.cache.Remove(CacheKeys.UpcomingConcerts);
    return CreateResult.SuccessResult(newConcert.Id);
}

데이터 일관성 보장

데이터베이스 쓰기 작업 직후 캐시를 업데이트하는 메커니즘을 구현합니다. 이벤트 기반 업데이트 또는 전용 데이터 관리 클래스를 사용하여 캐시 일관성을 보장합니다. 캐시를 데이터베이스 수정과 일관되게 동기화하는 것은 캐시 배제 패턴의 핵심입니다.

예제: 참조 구현은 메서드를 UpdateConcertAsync 사용하여 캐시의 데이터를 일관성 있게 유지합니다(다음 코드 참조).

public async Task<UpdateResult> UpdateConcertAsync(Concert existingConcert), 
{
   database.Update(existingConcert);
   await database.SaveChangesAsync();
   this.cache.Remove(CacheKeys.UpcomingConcerts);
   return UpdateResult.SuccessResult();
}

데이터베이스 성능 테스트

데이터베이스 성능은 애플리케이션의 성능 및 확장성에 영향을 줄 수 있습니다. 데이터베이스의 성능을 테스트하여 최적화되었는지 확인하는 것이 중요합니다. 몇 가지 주요 고려 사항에는 올바른 클라우드 지역 선택, 연결 풀링, 캐시 배제 패턴 및 쿼리 최적화가 포함됩니다.

  • 네트워크 홉을 테스트합니다. 애플리케이션을 클라우드로 이동하면 데이터베이스에 추가 네트워크 홉과 대기 시간이 발생할 수 있습니다. 새 클라우드 환경에서 도입하는 추가 홉을 테스트해야 합니다.

  • 성능 기준선을 설정합니다. 클라우드의 애플리케이션 성능을 비교하려면 온-프레미스 성능 메트릭을 초기 기준으로 사용해야 합니다.

다음 단계

GitHub 리포지토리의 지침에 따라 참조 구현을 배포합니다. 다음 리소스를 사용하여 .NET 애플리케이션, 웹앱, 클라우드 모범 사례 및 마이그레이션에 대해 자세히 알아봅니다.

.NET Framework 애플리케이션 업그레이드

참조 구현은 Windows를 실행하는 App Service에 배포되지만 Linux에서 실행할 수 있습니다. App Service Windows 플랫폼을 사용하면 최신 프레임워크 버전으로 업그레이드하지 않고도 .NET Framework 웹앱을 Azure로 이동할 수 있습니다. Linux App Service 계획 또는 최신 버전의 .NET에 추가된 새로운 기능 및 성능 향상에 대한 자세한 내용은 다음 지침을 참조하세요.

  • .NET Framework에서 .NET으로의 포팅 개요입니다. 특정 유형의 .NET 앱에 따라 지침을 가져옵니다.
  • .NET 업그레이드 도우미 개요입니다. .NET Framework 프로젝트 업그레이드와 관련된 많은 작업을 자동화하는 데 도움이 되는 콘솔 도구에 대해 알아봅니다.
  • Visual Studio에서 ASP.NET ASP.NET Core로 마이그레이션 웹앱의 증분 마이그레이션에 도움이 되는 Visual Studio 확장에 대해 알아봅니다.

Azure의 웹앱 소개

Azure의 .NET 웹 애플리케이션에 대한 실습 소개는 기본 .NET 웹 애플리케이션을 배포하기 위한 이 지침을 참조하세요.

클라우드 모범 사례

Azure 채택 및 아키텍처 지침은 다음을 참조하세요.

  • 클라우드 채택 프레임워크. 조직이 Azure에서 솔루션을 빌드하는 전략을 준비하고 실행하는 데 도움이 될 수 있습니다.
  • 잘 설계된 프레임워크입니다. 워크로드의 품질을 개선하는 데 사용할 수 있는 안내 테넌트를 설정합니다.

신뢰할 수 있는 웹앱 패턴보다 더 높은 SLO가 필요한 애플리케이션은 중요 업무용 워크로드를 참조 하세요.

마이그레이션 지침

다음 도구와 리소스는 온-프레미스 리소스를 Azure로 마이그레이션하는 데 도움이 될 수 있습니다.