이 문서에서는 최신 웹앱 패턴을 구현하는 방법을 보여 줍니다. 최신 웹앱 패턴은 클라우드에서 웹앱을 현대화하고 서비스 지향 아키텍처를 도입하는 방법을 정의합니다. 최신 웹앱 패턴은 Azure Well-Architected Framework의 원칙에 부합하고 신뢰할 수 있는 웹앱 패턴을 기반으로 하는 규범적인 아키텍처, 코드 및 구성 지침을 제공합니다.
최신 웹앱 패턴을 사용하는 이유는 무엇인가요?
최신 웹앱 패턴은 웹앱의 수요가 많은 영역을 최적화하는 데 도움이 됩니다. 이러한 영역을 분리하는 자세한 지침을 제공하여 비용 최적화를 위한 독립적인 스케일링을 지원합니다. 이 방법을 사용하면 중요한 구성 요소에 전용 리소스를 할당하여 전반적인 성능을 향상시킬 수 있습니다. 분리 가능한 서비스를 분리하면 앱의 한 부분에서 느려진 속도가 다른 부분에 영향을 주지 않도록 방지하여 안정성을 향상시킬 수 있습니다. 분리를 사용하면 개별 앱 구성 요소의 버전 관리도 독립적으로 수행할 수 있습니다.
최신 웹앱 패턴을 구현하는 방법
이 문서에는 최신 웹앱 패턴을 구현하기 위한 아키텍처, 코드 및 구성 지침이 포함되어 있습니다. 다음 링크를 사용하여 필요한 지침으로 이동합니다.
- 아키텍처 지침: 웹앱 구성 요소를 모듈화하고 적절한 PaaS(Platform as a Service) 솔루션을 선택하는 방법을 알아봅니다.
- 코드 지침: 분리된 구성 요소를 최적화하는 네 가지 디자인 패턴을 구현합니다. 스트랭글러 무화과, 큐 기반 부하 평준화, 경쟁 소비자 및 상태 엔드포인트 모니터링 패턴.
- 구성 지침: 분리된 구성 요소에 대한 인증, 권한 부여, 자동 크기 조정 및 컨테이너화를 구성합니다.
팁
최신 웹앱 패턴의 참조 구현 (샘플 앱)이 있습니다. 최신 웹앱 구현의 끝 상태를 나타냅니다. 이 문서에서 설명하는 모든 코드, 아키텍처 및 구성 업데이트를 제공하는 프로덕션 수준의 웹앱입니다. 참조 구현을 배포하고 사용하여 최신 웹앱 패턴의 구현을 안내합니다.
아키텍처 지침
최신 웹앱 패턴은 신뢰할 수 있는 웹앱 패턴을 기반으로 합니다. 구현하려면 몇 가지 추가 아키텍처 구성 요소가 필요합니다. 메시지 큐, 컨테이너 플랫폼, 분리된 서비스 데이터 저장소 및 컨테이너 레지스트리가 필요합니다(그림 1 참조).
그림 1. 최신 웹앱 패턴의 필수 아키텍처 요소입니다.
더 높은 SLO(서비스 수준 목표)를 위해 웹앱 아키텍처에 두 번째 지역을 추가할 수 있습니다. 두 번째 지역에서는 활성-활성 또는 활성-수동 구성을 지원하도록 트래픽을 두 번째 지역으로 라우팅하도록 부하 분산 장치를 구성해야 합니다. 허브 및 스포크 네트워크 토폴로지로 네트워크 방화벽과 같은 리소스를 중앙 집중화하고 공유합니다. 허브 가상 네트워크를 통해 컨테이너 리포지토리에 액세스합니다. 가상 머신이 있는 경우 허브 가상 네트워크에 요새 호스트를 추가하여 안전하게 관리합니다(그림 2 참조).
그림 2. 두 번째 지역 및 허브 및 스포크 네트워크 토폴로지의 최신 웹앱 패턴 아키텍처입니다.
아키텍처 분리
최신 웹앱 패턴을 구현하려면 기존 웹앱 아키텍처를 분리해야 합니다. 아키텍처를 분리하려면 모놀리식 애플리케이션을 각각 특정 기능 또는 기능을 담당하는 더 작고 독립적인 서비스로 분할해야 합니다. 이 프로세스에는 현재 웹앱을 평가하고, 아키텍처를 수정하고, 마지막으로 웹앱 코드를 컨테이너 플랫폼으로 추출해야 합니다. 목표는 분리되는 데 가장 도움이 되는 애플리케이션 서비스를 체계적으로 식별하고 추출하는 것입니다. 아키텍처를 분리하려면 다음 권장 사항을 따릅니다.
서비스 경계를 식별합니다. 도메인 기반 디자인 원칙을 적용하여 모놀리식 애플리케이션 내에서 제한된 컨텍스트를 식별합니다. 경계된 각 컨텍스트는 논리적 경계를 나타내며 별도의 서비스의 후보가 될 수 있습니다. 고유한 비즈니스 기능을 나타내고 종속성이 적은 서비스는 분리에 적합한 후보입니다.
서비스 혜택을 평가합니다. 독립적인 크기 조정을 통해 가장 많은 이점을 제공하는 서비스에 집중합니다. 이러한 서비스를 분리하고 처리 작업을 동기 작업에서 비동기 작업으로 변환하면 리소스 관리를 보다 효율적으로 수행하고, 독립적인 배포를 지원하며, 업데이트 또는 변경 중에 애플리케이션의 다른 부분에 영향을 줄 수 있습니다. 예를 들어 주문 체크 아웃을 주문 처리와 분리할 수 있습니다.
기술 타당성을 평가합니다. 현재 아키텍처를 검사하여 분리 프로세스에 영향을 줄 수 있는 기술 제약 조건 및 종속성을 식별합니다. 서비스에서 데이터를 관리하고 공유하는 방법을 계획합니다. 분리된 서비스는 자체 데이터를 관리하고 서비스 경계를 넘어 직접 데이터베이스 액세스를 최소화해야 합니다.
Azure 서비스를 배포합니다. 추출하려는 웹앱 서비스를 지원하는 데 필요한 Azure 서비스를 선택하고 배포합니다. 지침을 보려면 다음 Azure 서비스 선택 섹션을 사용합니다.
웹앱 서비스를 분리합니다. 시스템의 다른 부분과 상호 작용하기 위해 새로 추출된 웹앱 서비스에 대한 명확한 인터페이스 및 API를 정의합니다. 일관성과 무결성을 보장하면서 각 서비스가 자체 데이터를 관리할 수 있도록 하는 데이터 관리 전략을 설계합니다. 이 추출 프로세스 중에 사용할 특정 구현 전략 및 디자인 패턴은 코드 지침 섹션을 참조하세요.
분리된 서비스에 독립 스토리지를 사용합니다. 분리된 각 서비스에는 독립적인 버전 관리, 배포, 확장성을 용이하게 하고 데이터 무결성을 유지하기 위해 자체 격리된 데이터 저장소가 있어야 합니다. 예를 들어 참조 구현은 웹 API에서 티켓 렌더링 서비스를 분리하고 서비스가 API의 데이터베이스에 액세스할 필요가 없습니다. 대신, 서비스는 Azure Service Bus 메시지를 통해 티켓 이미지가 웹 API로 다시 생성된 URL을 전달하고 API는 해당 데이터베이스에 대한 경로를 유지합니다.
분리된 각 서비스에 대해 별도의 배포 파이프라인을 구현합니다. 별도의 배포 파이프라인을 사용하면 각 서비스를 자체적으로 업데이트할 수 있습니다. 회사 내의 다른 팀 또는 조직이 서로 다른 서비스를 소유하는 경우 별도의 배포 파이프라인을 사용하면 각 팀이 자체 배포를 제어할 수 있습니다. Jenkins, GitHub Actions 또는 Azure Pipelines와 같은 CI/CD(지속적인 통합 및 지속적인 업데이트) 도구를 사용하여 이러한 파이프라인을 설정합니다.
보안 제어를 수정합니다. 방화벽 규칙 및 액세스 제어를 포함하여 새 아키텍처를 고려하도록 보안 컨트롤이 업데이트되었는지 확인합니다.
올바른 Azure 서비스 선택
아키텍처의 각 Azure 서비스에 대해 잘 설계된 프레임워크의 관련 Azure 서비스 가이드 를 참조하세요. 최신 웹앱 패턴의 경우 비동기 메시징을 지원하는 메시징 시스템, 컨테이너화를 지원하는 애플리케이션 플랫폼 및 컨테이너 이미지 리포지토리가 필요합니다.
메시지 큐를 선택합니다. 메시지 큐는 서비스 지향 아키텍처의 중요한 부분입니다. 메시지 보낸 사람과 받는 사람을 분리하여 비동기 메시징을 사용하도록 설정합니다. 디자인 요구 사항을 지원하는 Azure 메시징 시스템을 선택하려면 Azure 메시징 서비스를 선택하는 방법에 대한 지침을 사용합니다. Azure에는 Azure Event Grid, Azure Event Hubs 및 Service Bus의 세 가지 메시징 서비스가 있습니다. Service Bus를 기본 선택으로 시작하고 Service Bus가 요구 사항을 충족하지 않는 경우 다른 두 옵션을 사용합니다.
서비스 사용 사례 Service Bus 엔터프라이즈 애플리케이션에서 고부가가치 메시지의 안정적이고 정렬된 트랜잭션 배달을 위해 Service Bus를 선택합니다. Event Grid 많은 수의 불연속 이벤트를 효율적으로 처리해야 하는 경우 Event Grid를 선택합니다. Event Grid는 대기 시간이 짧은 게시-구독 모델에서 많은 소규모 독립 이벤트(예: 리소스 상태 변경)를 구독자로 라우팅해야 하는 이벤트 기반 애플리케이션에 대해 확장할 수 있습니다. Event Hubs 원격 분석, 로그 또는 실시간 분석과 같이 처리량이 많은 대규모 데이터 수집을 위해 Event Hubs를 선택합니다. Event Hubs는 대량 데이터를 지속적으로 수집하고 처리해야 하는 스트리밍 시나리오에 최적화되어 있습니다. 컨테이너 서비스를 구현합니다. 컨테이너화하려는 애플리케이션 부분의 경우 컨테이너를 지원하는 애플리케이션 플랫폼이 필요합니다. Azure 컨테이너 서비스 선택 지침을 사용하여 결정을 내릴 수 있습니다. Azure에는 Azure Container Apps, AKS(Azure Kubernetes Service) 및 Azure 앱 Service의 세 가지 주요 컨테이너 서비스가 있습니다. Container Apps를 기본 선택으로 시작하고 Container Apps가 요구 사항을 충족하지 않는 경우 다른 두 옵션을 사용합니다.
서비스 사용 사례 Container Apps 이벤트 기반 애플리케이션에서 컨테이너의 크기를 자동으로 조정하고 관리하는 서버리스 플랫폼이 필요한 경우 Container Apps를 선택합니다. AKS 확장, 네트워킹 및 보안을 위해 Kubernetes 구성 및 고급 기능에 대한 자세한 제어가 필요한 경우 AKS를 선택합니다. Web Apps for Container 가장 간단한 PaaS 환경을 위해 App Service의 컨테이너용 웹앱을 선택합니다. 컨테이너 리포지토리를 구현합니다. 컨테이너 기반 컴퓨팅 서비스를 사용하는 경우 컨테이너 이미지를 저장할 리포지토리가 있어야 합니다. Docker Hub와 같은 공용 컨테이너 레지스트리 또는 Azure Container Registry와 같은 관리되는 레지스트리를 사용할 수 있습니다. Azure 지침의 컨테이너 레지스트리 소개를 사용하여 결정을 내릴 수 있습니다.
코드 지침
독립 서비스를 성공적으로 분리하고 추출하려면 스트랭글러 무화과 패턴, 큐 기반 부하 평준화 패턴, 경쟁 소비자 패턴, 상태 엔드포인트 모니터링 패턴 및 재시도 패턴과 같은 디자인 패턴으로 웹앱 코드를 업데이트해야 합니다.
스트랭글러 무화과 패턴: 스트랭글러 무화과 패턴은 모놀리식 애플리케이션에서 분리된 서비스로 기능을 증분 방식으로 마이그레이션합니다. 기본 웹앱에서 이 패턴을 구현하여 엔드포인트를 기반으로 트래픽을 전달하여 기능을 독립 서비스로 점진적으로 마이그레이션합니다.
큐 기반 부하 평준화 패턴: 큐 기반 부하 평준화 패턴은 큐를 버퍼로 사용하여 생산자와 소비자 간의 메시지 흐름을 관리합니다. 큐를 사용하여 메시지 흐름을 비동기적으로 관리하도록 분리된 서비스의 생산자 부분에 이 패턴을 구현합니다.
경쟁 소비자 패턴: 경쟁 소비자 패턴을 사용하면 분리된 서비스의 여러 인스턴스가 동일한 메시지 큐에서 독립적으로 읽고 메시지를 처리하기 위해 경쟁할 수 있습니다. 분리된 서비스에서 이 패턴을 구현하여 여러 인스턴스에 작업을 분산합니다.
상태 엔드포인트 모니터링 패턴: 상태 엔드포인트 모니터링 패턴은 웹앱의 여러 부분의 상태 및 상태를 모니터링하기 위한 엔드포인트를 노출합니다. (4a) 기본 웹앱에서 이 패턴을 구현합니다. (4b) 또한 분리된 서비스에서 구현하여 엔드포인트의 상태를 추적합니다.
다시 시도 패턴: 다시 시도 패턴은 간헐적으로 실패할 수 있는 작업을 다시 시도하여 일시적인 오류를 처리합니다. (5a) 메시지 큐 및 프라이빗 엔드포인트에 대한 호출과 같은 기본 웹앱의 다른 Azure 서비스에 대한 모든 아웃바운드 호출에서 이 패턴을 구현합니다. (5b) 또한 프라이빗 엔드포인트에 대한 호출에서 일시적인 오류를 처리하도록 분리된 서비스에서 이 패턴을 구현합니다.
각 디자인 패턴은 잘 설계된 프레임워크의 하나 이상의 핵심 요소에 부합하는 이점을 제공합니다(다음 표 참조).
디자인 패턴 | 구현 위치 | 안정성(RE) | 보안(SE) | CO(비용 최적화) | 운영 우수성(OE) | PE(성능 효율성) | 잘 설계된 프레임워크 원칙 지원 |
---|---|---|---|---|---|---|---|
스트랭글러 그림 패턴 | 기본 웹앱 | ✔ | ✔ | ✔ | RE:08 CO:07 CO:08 OE:06 OE:11 |
||
큐 기반 부하 평준화 패턴 | 분리된 서비스 생산자 | ✔ | ✔ | ✔ | RE:06 RE:07 CO:12 PE:05 |
||
경쟁 소비자 패턴 | 분리된 서비스 | ✔ | ✔ | ✔ | RE:05 RE:07 CO:05 CO:07 PE:05 PE:07 |
||
상태 엔드포인트 모니터링 패턴 | 주 웹앱 및 분리된 서비스 | ✔ | ✔ | ✔ | RE:07 RE:10 OE:07 PE:05 |
||
다시 시도 패턴 | 주 웹앱 및 분리된 서비스 | ✔ | RE:07 |
스트랭글러 무화과 패턴 구현
스트랭글러 무화과 패턴을 사용하여 모놀리식 코드베이스에서 새로운 독립 서비스로 기능을 점진적으로 마이그레이션합니다. 기존 모놀리식 코드 베이스에서 새 서비스를 추출하고 웹앱의 중요한 부분을 천천히 현대화합니다. 스트랭글러 무화과 패턴을 구현하려면 다음 권장 사항을 따릅니다.
라우팅 계층을 설정합니다. 모놀리식 웹앱 코드 베이스에서 엔드포인트를 기반으로 트래픽을 안내하는 라우팅 계층을 구현합니다. 필요에 따라 사용자 지정 라우팅 논리를 사용하여 트래픽을 전달하기 위한 특정 비즈니스 규칙을 처리합니다. 예를 들어 모놀리식 앱에 엔드포인트가 있고 해당 기능을 분리된 서비스로 이동한 경우
/users
라우팅 계층은 모든 요청을 새 서비스로/users
전달합니다.기능 롤아웃을 관리합니다. .NET 기능 관리 라이브러리를 사용하여 기능 플래그 및 단계적 롤아웃을 구현하여 분리된 서비스를 점진적으로 롤아웃 합니다. 기존 모놀리식 앱 라우팅은 분리된 서비스가 수신하는 요청 수를 제어해야 합니다. 약간의 요청으로 시작하고 안정성과 성능에 대한 확신을 얻으면서 시간이 지남에 따라 사용량을 증가합니다. 예를 들어 참조 구현은 티켓 렌더링 기능의 상당 부분을 처리하도록 점진적으로 도입될 수 있는 독립 실행형 서비스로 티켓 렌더링 기능을 추출합니다. 새 서비스는 안정성과 성능을 증명하므로 결국 모놀리식에서 전체 티켓 렌더링 기능을 인수하여 전환을 완료할 수 있습니다.
외관 서비스를 사용합니다(필요한 경우). 외관 서비스는 단일 요청이 여러 서비스와 상호 작용해야 하거나 클라이언트에서 기본 시스템의 복잡성을 숨기려는 경우에 유용합니다. 그러나 분리된 서비스에 공용 API가 없는 경우 외관 서비스가 필요하지 않을 수 있습니다. 모놀리식 웹앱 코드 베이스에서 요청을 적절한 백 엔드(모놀리식 또는 마이크로 서비스)로 라우팅하는 외관 서비스를 구현합니다. 분리된 새 서비스에서는 새 서비스가 외관을 통해 액세스할 때 요청을 독립적으로 처리할 수 있는지 확인합니다.
큐 기반 부하 평준화 패턴 구현
즉시 응답이 필요하지 않은 작업을 비동기적으로 처리하도록 분리된 서비스의 생산자 부분에 큐 기반 부하 평준화 패턴을 구현합니다. 이 패턴은 큐를 사용하여 워크로드 배포를 관리하여 전반적인 시스템 응답성 및 확장성을 향상시킵니다. 분리된 서비스가 일관된 속도로 요청을 처리할 수 있습니다. 이 패턴을 효과적으로 구현하려면 다음 권장 사항을 따릅니다.
차단 해제 메시지 큐를 사용합니다. 큐에 메시지를 보내는 프로세스가 분리된 서비스가 큐의 메시지를 처리할 때까지 기다리는 동안 다른 프로세스를 차단하지 않는지 확인합니다. 프로세스에 분리된 서비스 작업의 결과가 필요한 경우 대기 중인 작업이 완료되기를 기다리는 동안 상황을 처리하는 다른 방법이 있습니다. 예를 들어 참조 구현에서는 Service Bus 및
await
키워드를messageSender.PublishAsync()
사용하여 이 코드를 실행하는 스레드를 차단하지 않고 메시지를 비동기적으로 큐에 게시합니다.// Asynchronously publish a message without blocking the calling thread await messageSender.PublishAsync(new TicketRenderRequestMessage(Guid.NewGuid(), ticket, null, DateTime.Now), CancellationToken.None);
이 방법을 사용하면 주 애플리케이션이 응답성을 유지하고 다른 작업을 동시에 처리할 수 있으며 분리된 서비스는 큐에 대기 중인 요청을 관리 가능한 속도로 처리합니다.
메시지 다시 시도 및 제거를 구현합니다. 성공적으로 처리할 수 없는 큐에 대기 중인 메시지의 처리를 다시 시도하는 메커니즘을 구현합니다. 오류가 지속되면 큐에서 이러한 메시지를 제거해야 합니다. 예를 들어 Service Bus에는 기본 제공 재시도 및 배달 못 한 편지 큐 기능이 있습니다.
idempotent 메시지 처리를 구성합니다. 큐에서 메시지를 처리하는 논리는 메시지를 두 번 이상 처리할 수 있는 경우를 처리하기 위해 idempotent여야 합니다. 예를 들어 참조 구현은 메시지를 한 번만 처리하고
ReceiveMode = ServiceBusReceiveMode.PeekLock
실패 시 다시 처리할 수 있도록 하는 데 사용합니다AutoCompleteMessages = true
ServiceBusClient.CreateProcessor
(다음 코드 참조).// Create a processor for idempotent message processing var processor = serviceBusClient.CreateProcessor(path, new ServiceBusProcessorOptions { // Allow the messages to be auto-completed // if processing finishes without failure. AutoCompleteMessages = true, // PeekLock mode provides reliability in that unsettled messages // will be redelivered on failure. ReceiveMode = ServiceBusReceiveMode.PeekLock, // Containerized processors can scale at the container level // and need not scale via the processor options. MaxConcurrentCalls = 1, PrefetchCount = 0 });
환경의 변경 내용을 관리합니다. 비동기 처리로 인해 작업이 즉시 완료되지 않을 수 있습니다. 올바른 기대치를 설정하고 혼동을 피하기 위해 작업이 여전히 처리되는 경우 사용자에게 알려야 합니다. 시각적 신호 또는 메시지를 사용하여 작업이 진행 중임을 나타냅니다. 전자 메일 또는 푸시 알림과 같은 작업이 완료되면 사용자에게 알림을 받을 수 있는 옵션을 제공합니다.
경쟁 소비자 패턴 구현
분리된 서비스에서 경쟁 소비자 패턴을 구현하여 메시지 큐에서 들어오는 작업을 관리합니다. 이 패턴에는 분리된 서비스의 여러 인스턴스에 태스크를 분산하는 작업이 포함됩니다. 이러한 서비스는 큐에서 메시지를 처리하여 부하 분산을 강화하고 동시 요청을 처리하는 시스템 용량을 향상시킵니다. 경쟁 소비자 패턴은 다음과 같은 경우에 효과적입니다.
- 메시지 처리 시퀀스는 중요하지 않습니다.
- 큐는 잘못된 형식의 메시지의 영향을 받지 않습니다.
- 처리 작업은 idempotent이므로 초기 애플리케이션을 넘어 결과를 변경하지 않고도 여러 번 적용할 수 있습니다.
경쟁 소비자 패턴을 구현하려면 다음 권장 사항을 따릅니다.
동시 메시지를 처리합니다. 큐에서 메시지를 수신할 때 시스템이 여러 메시지를 동시에 처리하도록 설계되었는지 확인합니다. 별도의 소비자가 각 메시지를 처리하도록 최대 동시 호출을 1로 설정합니다.
프리페치를 사용하지 않도록 설정합니다. 소비자가 준비가 된 경우에만 메시지를 가져오도록 메시지의 메시지 프리페치를 사용하지 않도록 설정합니다.
신뢰할 수 있는 메시지 처리 모드를 사용합니다. 피킹록(또는 해당 항목)과 같은 신뢰할 수 있는 처리 모드를 사용하여 처리에 실패한 메시지를 자동으로 다시 시도합니다. 이 모드는 삭제 우선 메서드에 대한 안정성을 향상시킵니다. 한 작업자가 메시지를 처리하지 못하는 경우 메시지가 여러 번 처리되더라도 다른 작업자가 오류 없이 처리할 수 있어야 합니다.
오류 처리를 구현합니다. 형식이 잘못되었거나 처리할 수 없는 메시지를 별도의 배달 못 한 편지 큐로 라우팅합니다. 이 디자인은 반복적인 처리를 방지합니다. 예를 들어 메시지 처리 중에 예외를 catch하고 문제가 있는 메시지를 별도의 큐로 이동할 수 있습니다.
순서가 다른 메시지를 처리합니다. 순서가 벗어난 메시지를 처리하도록 소비자를 디자인합니다. 여러 병렬 소비자는 메시지를 순서대로 처리할 수 있음을 의미합니다.
큐 길이에 따라 크기 조정합니다. 큐에서 메시지를 사용하는 서비스는 큐 길이에 따라 자동 크기 조정되어야 합니다. 크기 조정 기반 자동 크기 조정을 사용하면 들어오는 메시지의 급증을 효율적으로 처리할 수 있습니다.
메시지 회신 큐를 사용합니다. 시스템에서 메시지 후 처리에 대한 알림이 필요한 경우 전용 회신 또는 응답 큐를 설정합니다. 이 설정은 운영 메시징을 알림 프로세스와 나눕니다.
상태 비지정 서비스를 사용합니다. 상태 비정상 서비스를 사용하여 큐에서 요청을 처리하는 것이 좋습니다. 이를 통해 쉽게 크기를 조정하고 리소스를 효율적으로 사용할 수 있습니다.
로깅을 구성합니다. 메시지 처리 워크플로 내에서 로깅 및 특정 예외 처리를 통합합니다. serialization 오류를 캡처하고 이러한 문제가 있는 메시지를 배달 못 한 편지 메커니즘으로 보내는 데 집중합니다. 이러한 로그는 문제 해결을 위한 유용한 인사이트를 제공합니다.
예를 들어 참조 구현은 Container Apps에서 실행되는 상태 비지방 서비스에서 경쟁 소비자 패턴을 사용하여 Service Bus 큐에서 티켓 렌더링 요청을 처리합니다. 다음을 사용하여 큐 프로세서를 구성합니다.
- AutoCompleteMessages: 오류 없이 처리되는 경우 자동으로 메시지를 완료합니다.
- ReceiveMode: PeekLock 모드를 사용하고 메시지가 정해지지 않은 경우 메시지를 다시 배달합니다.
- MaxConcurrentCalls: 한 번에 하나의 메시지를 처리하려면 1로 설정합니다.
- PrefetchCount: 메시지 프리페치를 방지하려면 0으로 설정합니다.
프로세서는 문제 해결 및 모니터링에 도움이 되는 메시지 처리 세부 정보를 기록합니다. 역직렬화 오류를 캡처하고 잘못된 메시지를 배달 못 한 편지 큐로 라우팅하여 잘못된 메시지를 반복적으로 처리하지 못하게 합니다. 서비스는 컨테이너 수준에서 확장되므로 큐 길이에 따라 메시지 급증을 효율적으로 처리할 수 있습니다.
// Create a processor for the given queue that will process
// incoming messages.
var processor = serviceBusClient.CreateProcessor(path, new ServiceBusProcessorOptions
{
// Allow the messages to be auto-completed
// if processing finishes without failure.
AutoCompleteMessages = true,
// PeekLock mode provides reliability in that unsettled messages
// are redelivered on failure.
ReceiveMode = ServiceBusReceiveMode.PeekLock,
// Containerized processors can scale at the container level
// and need not scale via the processor options.
MaxConcurrentCalls = 1,
PrefetchCount = 0
});
// Called for each message received by the processor.
processor.ProcessMessageAsync += async args =>
{
logger.LogInformation("Processing message {MessageId} from {ServiceBusNamespace}/{Path}", args.Message.MessageId, args.FullyQualifiedNamespace, args.EntityPath);
// Unhandled exceptions in the handler will be caught by
// the processor and result in abandoning and dead-lettering the message.
try
{
var message = args.Message.Body.ToObjectFromJson<T>();
await messageHandler(message, args.CancellationToken);
logger.LogInformation("Successfully processed message {MessageId} from {ServiceBusNamespace}/{Path}",args.Message.MessageId, args.FullyQualifiedNamespace, args.EntityPath);
}
catch (JsonException)
{
logger.LogError("Invalid message body; could not be deserialized to {Type}", typeof(T));
await args.DeadLetterMessageAsync(args.Message, $"Invalid message body; could not be deserialized to {typeof(T)}",cancellationToken: args.CancellationToken);
}
};
상태 엔드포인트 모니터링 패턴 구현
주 앱 코드에서 상태 엔드포인트 모니터링 패턴을 구현하고 분리된 서비스 코드를 구현하여 애플리케이션 엔드포인트의 상태를 추적합니다. AKS 또는 Container Apps와 같은 오케스트레이터는 이러한 엔드포인트를 폴링하여 서비스 상태를 확인하고 비정상 인스턴스를 다시 시작할 수 있습니다. ASP.NET 핵심 앱은 엔드포인트 상태 데이터 및 키 종속성을 효율적으로 제공하기 위해 전용 상태 검사 미들웨어 를 추가할 수 있습니다. 상태 엔드포인트 모니터링 패턴을 구현하려면 다음 권장 사항을 따릅니다.
상태 검사를 구현합니다. ASP.NET Core 상태 검사 미들웨어를 사용하여 상태 검사 엔드포인트를 제공합니다.
종속성 유효성을 검사합니다. 상태 검사에서 데이터베이스, 스토리지 및 메시징 시스템과 같은 주요 종속성의 가용성을 확인하는지 확인합니다. Microsoft가 아닌 패키지인 AspNetCore.Diagnostics.HealthChecks는 많은 일반적인 앱 종속성에 대한 상태 검사 종속성 검사를 구현할 수 있습니다.
예를 들어 참조 구현은 ASP.NET Core 상태 검사 미들웨어를 사용하여 개체의
AddHealthChecks()
메서드를 사용하여 상태 검사 엔드포인트를builder.Services
노출합니다. 이 코드는 패키지의 일부인 메서드 및 메서드를 사용하여 주요 종속성, Azure Blob Storage 및AddAzureServiceBusQueue()
Service Bus 큐AddAzureBlobStorage()
의 가용성을AspNetCore.Diagnostics.HealthChecks
확인합니다. Container Apps를 사용하면 모니터링되는 상태 프로브를 구성하여 앱이 정상 상태인지 아니면 재활용이 필요한지 여부를 측정할 수 있습니다.// Add health checks, including health checks for Azure services // that are used by this service. // The Blob Storage and Service Bus health checks are provided by // AspNetCore.Diagnostics.HealthChecks // (a popular open source project) rather than by Microsoft. // https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks builder.Services.AddHealthChecks() .AddAzureBlobStorage(options => { // AddAzureBlobStorage will use the BlobServiceClient registered in DI // We just need to specify the container name options.ContainerName = builder.Configuration.GetRequiredConfigurationValue("App:StorageAccount:Container"); }) .AddAzureServiceBusQueue( builder.Configuration.GetRequiredConfigurationValue("App:ServiceBus:Host"), builder.Configuration.GetRequiredConfigurationValue("App:ServiceBus:RenderRequestQueueName"), azureCredentials); // Further app configuration omitted for brevity app.MapHealthChecks("/health");
Azure 리소스를 구성합니다. 앱의 상태 검사 URL을 사용하여 활동성 및 준비 상태를 확인하도록 Azure 리소스를 구성합니다. 예를 들어 참조 구현은 Bicep을 사용하여 상태 검사 URL을 구성하여 Azure 리소스의 활동성 및 준비 상태를 확인합니다. 초기 지연 시간 2초 후 10초마다 엔드포인트에 적중
/health
하는 활동성 프로브입니다.probes: [ { type: 'liveness' httpGet: { path: '/health' port: 8080 } initialDelaySeconds: 2 periodSeconds: 10 } ]
재시도 패턴 구현
재시도 패턴을 사용하면 애플리케이션이 일시적인 오류로부터 복구할 수 있습니다. 재시도 패턴은 신뢰할 수 있는 웹앱 패턴의 핵심이므로 웹앱은 이미 다시 시도 패턴을 사용해야 합니다. 웹앱에서 추출한 분리된 서비스에서 발급한 메시징 시스템 및 요청에 재시도 패턴을 적용합니다. 다시 시도 패턴을 구현하려면 다음 권장 사항을 따릅니다.
다시 시도 옵션을 구성합니다. 메시지 큐와 통합할 때 적절한 재시도 설정을 사용하여 큐와의 상호 작용을 담당하는 클라이언트를 구성해야 합니다. 최대 재시도 횟수, 재시도 사이의 지연 및 최대 지연과 같은 매개 변수를 지정합니다.
지수 백오프를 사용합니다. 재시도를 위한 지수 백오프 전략을 구현합니다. 즉, 각 재시도 사이의 시간을 기하급수적으로 늘려 실패율이 높은 기간 동안 시스템의 부하를 줄이는 데 도움이 됩니다.
SDK 재시도 기능을 사용합니다. Service Bus 또는 Blob Storage와 같은 특수한 SDK가 있는 서비스의 경우 기본 제공 재시도 메커니즘을 사용합니다. 기본 제공 재시도 메커니즘은 서비스의 일반적인 사용 사례에 맞게 최적화되어 있으며, 필요한 구성을 줄여 재시도를 보다 효과적으로 처리할 수 있습니다. 예를 들어 참조 구현은 Service Bus SDK(
ServiceBusClient
및ServiceBusRetryOptions
)의 기본 제공 재시도 기능을 사용합니다. 개체는ServiceBusRetryOptions
MaxRetries, Delay, MaxDelay 및 TryTimeout과 같은 재시도 설정을 구성하기 위해 설정을MessageBusOptions
가져옵니다.// ServiceBusClient is thread-safe and can be reused for the lifetime // of the application. services.AddSingleton(sp => { var options = sp.GetRequiredService<IOptions<MessageBusOptions>>().Value; var clientOptions = new ServiceBusClientOptions { RetryOptions = new ServiceBusRetryOptions { Mode = ServiceBusRetryMode.Exponential, MaxRetries = options.MaxRetries, Delay = TimeSpan.FromSeconds(options.BaseDelaySecondsBetweenRetries), MaxDelay = TimeSpan.FromSeconds(options.MaxDelaySeconds), TryTimeout = TimeSpan.FromSeconds(options.TryTimeoutSeconds) } }; return new ServiceBusClient(options.Host, azureCredential ?? new DefaultAzureCredential(), clientOptions); });
HTTP 클라이언트용 표준 복원력 라이브러리를 채택합니다. HTTP 통신의 경우 Polly 또는
Microsoft.Extensions.Http.Resilience
.와 같은 표준 복원력 라이브러리를 통합합니다. 이러한 라이브러리는 외부 웹 서비스와의 통신을 관리하는 데 중요한 포괄적인 재시도 메커니즘을 제공합니다.메시지 잠금을 처리합니다. 메시지 기반 시스템의 경우 데이터 손실 없이 다시 시도(예: 사용 가능한 경우 "피킹 잠금" 모드 사용)를 지원하는 메시지 처리 전략을 구현합니다. 실패한 메시지가 효과적으로 다시 시도되고 반복된 실패 후 배달 못 한 편지 큐로 이동되었는지 확인합니다.
분산 추적 구현
애플리케이션이 서비스 지향적이고 해당 구성 요소가 분리됨에 따라 서비스 간의 실행 흐름을 모니터링하는 것이 중요합니다. 최신 웹앱 패턴은 분산 추적을 지원하는 OpenTelemetry API를 통해 애플리케이션 상태 및 성능에 대한 가시성을 위해 Application Insights 및 Azure Monitor를 사용합니다.
분산 추적은 여러 서비스를 트래버스할 때 사용자 요청을 추적합니다. 요청이 수신되면 HTTP 헤더를 통해 다른 구성 요소에 전달되는 추적 식별자와 종속성 호출 중에 Service Bus 속성으로 태그가 지정됩니다. 그런 다음 추적 및 로그에는 추적 식별자와 특정 구성 요소 및 해당 부모 활동에 해당하는 활동 식별자(또는 범위 식별자)가 모두 포함됩니다. Application Insights와 같은 모니터링 도구는 분산 애플리케이션을 모니터링하는 데 중요한 다양한 서비스에 걸쳐 활동 및 로그 트리를 표시하는 데 사용합니다.
OpenTelemetry 라이브러리를 설치합니다. 계측 라이브러리를 사용하여 공통 구성 요소의 추적 및 메트릭을 사용하도록 설정합니다. 필요한 경우 사용자 지정 계측을
System.Diagnostics.ActivitySource
System.Diagnostics.Activity
추가합니다. 내보내기 라이브러리를 사용하여 OpenTelemetry 진단을 수신 대기하고 영구 저장소에 기록합니다. 기존 내보내기를 활용하거나System.Diagnostics.ActivityListener
.OpenTelemetry를 설정합니다. OpenTelemetry(
Azure.Monitor.OpenTelemetry.AspNetCore
)의 Azure Monitor 배포를 사용합니다. 진단을 Application Insights로 내보내고 .NET 런타임 및 ASP.NET Core의 일반적인 메트릭, 추적, 로그 및 예외에 대한 기본 제공 계측을 포함하는지 확인합니다. SQL, Redis 및 Azure SDK 클라이언트에 대한 다른 OpenTelemetry 계측 패키지를 포함합니다.모니터링 및 분석. 구성한 후 로그, 추적, 메트릭 및 예외가 캡처되어 Application Insights로 전송되는지 확인합니다. Application Insights가 HTTP 및 Service Bus 경계에서 엔드 투 엔드 추적 가시성을 제공할 수 있도록 추적, 활동 및 부모 활동 식별자가 포함되어 있는지 확인합니다. 이 설정을 사용하여 여러 서비스에서 애플리케이션의 활동을 효과적으로 모니터링하고 분석할 수 있습니다.
최신 웹앱 샘플은 OpenTelemetry(Azure.Monitor.OpenTelemetry.AspNetCore
)의 Azure Monitor 배포를 사용합니다. SQL, Redis 및 Azure SDK 클라이언트에 더 많은 계측 패키지가 사용됩니다. OpenTelemetry는 다음과 같이 최신 웹앱 샘플 티켓 렌더링 서비스에서 구성됩니다.
builder.Logging.AddOpenTelemetry(o =>
{
o.IncludeFormattedMessage = true;
o.IncludeScopes = true;
});
builder.Services.AddOpenTelemetry()
.UseAzureMonitor(o => o.ConnectionString = appInsightsConnectionString)
.WithMetrics(metrics =>
{
metrics.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddRuntimeInstrumentation();
})
.WithTracing(tracing =>
{
tracing.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddSource("Azure.*");
});
이 메서드는 builder.Logging.AddOpenTelemetry
OpenTelemetry를 통해 모든 로깅을 라우팅하여 애플리케이션 전체에서 일관된 추적 및 로깅을 보장합니다. OpenTelemetry 서비스를 builder.Services.AddOpenTelemetry
등록하면 애플리케이션이 진단을 수집하고 내보내도록 설정되며, 그런 다음, Application Insights UseAzureMonitor
로 전송됩니다. 또한 Service Bus 및 HTTP 클라이언트와 같은 구성 요소에 대한 클라이언트 계측은 구성을 통해 WithMetrics
구성되며 WithTracing
, 기존 클라이언트 사용을 변경하지 않고도 자동 메트릭 및 추적 수집을 사용하도록 설정하고 구성에 대한 업데이트만 수행합니다.
구성 지침
다음 섹션에서는 구성 업데이트 구현에 대한 지침을 제공합니다. 각 섹션은 잘 설계된 프레임워크의 하나 이상의 기둥에 맞춥니다.
구성 | 안정성(RE) | 보안(SE) | CO(비용 최적화) | 운영 우수성(OE) | PE(성능 효율성) | 잘 설계된 프레임워크 원칙 지원 |
---|---|---|---|---|---|---|
인증 및 권한 부여 구성 | ✔ | ✔ | SE:05 OE:10 |
|||
독립적인 자동 크기 조정 구현 | ✔ | ✔ | ✔ | RE:06 CO:12 PE:05 |
||
서비스 배포 컨테이너화 | ✔ | ✔ | CO:13 PE:09 PE:03 |
인증 및 권한 부여 구성
웹앱에 추가하는 새 Azure 서비스(워크로드 ID)에 대한 인증 및 권한 부여를 구성하려면 다음 권장 사항을 따릅니다.
각 새 서비스에 대해 관리 ID를 사용합니다. 각 독립 서비스에는 고유한 ID가 있어야 하며 서비스 대 서비스 인증에 관리 ID를 사용해야 합니다. 관리 ID는 코드에서 자격 증명을 관리하고 자격 증명 누출 위험을 줄일 필요가 없습니다. 코드 또는 구성 파일에 연결 문자열 같은 중요한 정보를 배치하지 않도록 도와줍니다.
각 새 서비스에 최소 권한을 부여합니다. 각 새 서비스 ID에 필요한 권한만 할당합니다. 예를 들어 ID가 컨테이너 레지스트리로 푸시하기만 하면 되는 경우 끌어오기 권한을 부여하지 마세요. 이러한 사용 권한을 정기적으로 검토하고 필요에 따라 조정합니다. 배포 및 애플리케이션과 같은 다양한 역할에 서로 다른 ID를 사용합니다. 이렇게 하면 하나의 ID가 손상된 경우 잠재적인 손상이 제한됩니다.
IaC(Infrastructure As Code)를 채택합니다. Bicep 또는 유사한 IaC 도구를 사용하여 클라우드 리소스를 정의하고 관리합니다. IaC는 배포에서 보안 구성의 일관된 애플리케이션을 보장하고 인프라 설정을 버전 제어할 수 있도록 합니다.
사용자(사용자 ID)에 대한 인증 및 권한 부여를 구성하려면 다음 권장 사항을 따릅니다.
사용자에게 최소 권한을 부여합니다. 서비스와 마찬가지로 사용자에게 작업을 수행하는 데 필요한 권한만 부여되었는지 확인합니다. 이러한 사용 권한을 정기적으로 검토하고 조정합니다.
정기적인 보안 감사를 수행합니다. 보안 설정을 정기적으로 검토하고 감사합니다. 잘못된 구성 또는 불필요한 사용 권한을 찾아 즉시 수정합니다.
참조 구현은 IaC를 사용하여 각 ID에 추가된 서비스 및 특정 역할에 관리 ID를 할당합니다. 배포(), 애플리케이션 소유자() 및 Container Apps 애플리케이션(containerRegistryPushRoleId
)에containerRegistryPushRoleId
대한 역할 및 권한 액세스를 정의합니다(containerRegistryPullRoleId
다음 코드 참조).
roleAssignments: \[
{
principalId: deploymentSettings.principalId
principalType: deploymentSettings.principalType
roleDefinitionIdOrName: containerRegistryPushRoleId
}
{
principalId: ownerManagedIdentity.outputs.principal_id
principalType: 'ServicePrincipal'
roleDefinitionIdOrName: containerRegistryPushRoleId
}
{
principalId: appManagedIdentity.outputs.principal_id
principalType: 'ServicePrincipal'
roleDefinitionIdOrName: containerRegistryPullRoleId
}
\]
참조 구현은 배포 시 관리 ID를 새 Container Apps ID로 할당합니다(다음 코드 참조).
module renderingServiceContainerApp 'br/public:avm/res/app/container-app:0.1.0' = {
name: 'application-rendering-service-container-app'
scope: resourceGroup()
params: {
// Other parameters omitted for brevity
managedIdentities: {
userAssignedResourceIds: [
managedIdentity.id
]
}
}
}
독립적인 자동 크기 조정 구성
최신 웹앱 패턴은 모놀리식 아키텍처를 분리하기 시작하고 서비스 분리를 도입합니다. 웹앱 아키텍처를 분리하는 경우 분리된 서비스를 독립적으로 확장할 수 있습니다. 전체 웹앱이 아닌 독립적인 웹앱 서비스를 지원하도록 Azure 서비스를 확장하면 요구 사항을 충족하는 동안 비용 크기 조정이 최적화됩니다. 컨테이너를 자동 크기 조정하려면 다음 권장 사항을 따릅니다.
상태 비지정 서비스를 사용합니다. 서비스가 상태 비 상태인지 확인합니다. .NET 애플리케이션에 In-process 세션 상태가 포함된 경우 Redis와 같은 분산 캐시 또는 SQL Server와 같은 데이터베이스로 외부화합니다.
자동 크기 조정 규칙을 구성합니다. 서비스에 대한 가장 비용 효율적인 제어를 제공하는 자동 크기 조정 구성을 사용합니다. 컨테이너화된 서비스의 경우 Kubernetes KEDA(Event-Driven Autoscaler)와 같은 이벤트 기반 크기 조정은 종종 이벤트 메트릭에 따라 크기를 조정할 수 있도록 세분화된 제어를 제공합니다. Container Apps 및 AKS는 KEDA를 지원합니다. App Service와 같이 KEDA를 지원하지 않는 서비스의 경우 플랫폼 자체에서 제공하는 자동 크기 조정 기능을 사용합니다. 이러한 기능에는 메트릭 기반 규칙 또는 HTTP 트래픽을 기반으로 하는 크기 조정이 포함되는 경우가 많습니다.
최소 복제본을 구성합니다. 콜드 시작을 방지하려면 복제본을 하나 이상 유지하도록 자동 크기 조정 설정을 구성합니다. 콜드 시작은 중지된 상태에서 서비스를 초기화하는 경우이며, 종종 지연된 응답을 만듭니다. 비용 최소화가 우선 순위이고 콜드 시작 지연을 허용할 수 있는 경우 자동 크기 조정을 구성할 때 최소 복제본 수를 0으로 설정합니다.
쿨다운 기간을 구성합니다. 적절한 쿨다운 기간을 적용하여 크기 조정 이벤트 간에 지연을 발생합니다. 목표는 임시 부하 급증에 의해 트리거되는 과도한 크기 조정 작업을 방지하는 것입니다.
큐 기반 크기 조정을 구성합니다. 애플리케이션에서 Service Bus와 같은 메시지 큐를 사용하는 경우 요청 메시지가 있는 큐의 길이에 따라 크기를 조정하도록 자동 크기 조정 설정을 구성합니다. Scaler는 큐의 모든 N 메시지에 대해 하나의 서비스 복제본을 유지 관리하는 것을 목표로 합니다(반올림됨).
예를 들어 참조 구현은 Service Bus KEDA 스케일러를 사용하여 큐의 길이에 따라 컨테이너 앱의 크기를 조정합니다. service-bus-queue-length-rule
지정된 Service Bus 큐의 길이에 따라 서비스의 크기를 조정합니다. 매개 변수는 messageCount
10으로 설정되므로 scaler에는 큐에 있는 10개 메시지마다 하나의 서비스 복제본이 있습니다. 및 scaleMinReplicas
매개 변수는 scaleMaxReplicas
서비스의 최대 및 최소 복제본 수를 설정합니다. queue-connection-string
Service Bus 큐에 대한 연결 문자열 포함하는 비밀은 Azure Key Vault에서 검색됩니다. 이 비밀은 Service Bus에 대한 스케일러를 인증하는 데 사용됩니다.
scaleRules: [
{
name: 'service-bus-queue-length-rule'
custom: {
type: 'azure-servicebus'
metadata: {
messageCount: '10'
namespace: renderRequestServiceBusNamespace
queueName: renderRequestServiceBusQueueName
}
auth: [
{
secretRef: 'render-request-queue-connection-string'
triggerParameter: 'connection'
}
]
}
}
]
scaleMaxReplicas: 5
scaleMinReplicas: 0
서비스 배포 컨테이너화
컨테이너화는 앱이 작동하기 위한 모든 종속성이 광범위한 호스트에 안정적으로 배포될 수 있는 경량 이미지로 캡슐화됨을 의미합니다. 배포를 컨테이너화하려면 다음 권장 사항을 따릅니다.
도메인 경계를 식별합니다. 먼저 모놀리식 애플리케이션 내에서 도메인 경계를 식별합니다. 이렇게 하면 별도의 서비스로 추출할 수 있는 애플리케이션 부분을 결정하는 데 도움이 됩니다.
Docker 이미지를 만듭니다. .NET 서비스에 대한 Docker 이미지를 만들 때는 끌 기반 이미지를 사용합니다. 이러한 이미지에는 .NET을 실행하는 데 필요한 최소 패키지 집합만 포함되어 패키지 크기와 공격 노출 영역을 모두 최소화합니다.
다단계 Dockerfile을 사용합니다. 런타임 컨테이너 이미지에서 빌드 시간 자산을 분리하도록 다단계 Dockerfile을 구현합니다. 프로덕션 이미지를 작고 안전하게 유지하는 데 도움이 됩니다.
비루트 사용자로 실행합니다. .NET 컨테이너를 사용자 이름 또는 UID, $APP_UID를 통해 비루트 사용자로 실행하여 최소 권한 원칙에 맞춥니다. 손상된 컨테이너의 잠재적인 영향을 제한합니다.
포트 8080에서 수신 대기합니다. 비루트 사용자로 실행하는 경우 포트 8080에서 수신 대기하도록 애플리케이션을 구성합니다. 이는 비루트 사용자에 대한 일반적인 규칙입니다.
종속성을 캡슐화합니다. 앱이 작동하기 위한 모든 종속성이 Docker 컨테이너 이미지에 캡슐화되어 있는지 확인합니다. 캡슐화를 사용하면 다양한 호스트에 앱을 안정적으로 배포할 수 있습니다.
올바른 기본 이미지를 선택합니다. 선택하는 기본 이미지는 배포 환경에 따라 달라집니다. 예를 들어 Container Apps에 배포하는 경우 Linux Docker 이미지를 사용해야 합니다.
예를 들어 참조 구현은 다단계 빌드 프로세스를 사용합니다. 초기 단계는 전체 SDK 이미지(mcr.microsoft.com/dotnet/sdk:8.0-jammy
)를 사용하여 애플리케이션을 컴파일하고 빌드합니다. 최종 런타임 이미지는 SDK 및 빌드 아티팩트가 제외되는 기본 이미지에서 chiseled
만들어집니다. 서비스는 비루트 사용자(USER $APP_UID
)로 실행되고 포트 8080을 노출합니다. 애플리케이션이 작동하는 데 필요한 종속성은 프로젝트 파일을 복사하고 패키지를 복원하는 명령에 의해 입증된 대로 Docker 이미지 내에 포함됩니다. Linux 기반 이미지(mcr.microsoft.com/dotnet/aspnet:8.0-jammy-chiseled
)를 사용하면 배포를 위해 Linux 컨테이너가 필요한 Container Apps와의 호환성을 보장합니다.
# Build in a separate stage to avoid copying the SDK into the final image
FROM mcr.microsoft.com/dotnet/sdk:8.0-jammy AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
# Restore packages
COPY ["Relecloud.TicketRenderer/Relecloud.TicketRenderer.csproj", "Relecloud.TicketRenderer/"]
COPY ["Relecloud.Messaging/Relecloud.Messaging.csproj", "Relecloud.Messaging/"]
COPY ["Relecloud.Models/Relecloud.Models.csproj", "Relecloud.Models/"]
RUN dotnet restore "./Relecloud.TicketRenderer/Relecloud.TicketRenderer.csproj"
# Build and publish
COPY . .
WORKDIR "/src/Relecloud.TicketRenderer"
RUN dotnet publish "./Relecloud.TicketRenderer.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
# Chiseled images contain only the minimal set of packages needed for .NET 8.0
FROM mcr.microsoft.com/dotnet/aspnet:8.0-jammy-chiseled AS final
WORKDIR /app
EXPOSE 8080
# Copy the published app from the build stage
COPY --from=build /app/publish .
# Run as non-root user
USER $APP_UID
ENTRYPOINT ["dotnet", "./Relecloud.TicketRenderer.dll"]
참조 구현 배포
.NET용 최신 웹앱 패턴의 참조 구현을 배포합니다. 리포지토리의 개발 및 프로덕션 배포에 대한 지침이 있습니다. 배포 후에는 디자인 패턴을 시뮬레이션하고 관찰할 수 있습니다.
그림 3. 참조 구현의 아키텍처입니다. 이 아키텍처의 Visio 파일을 다운로드합니다.