자체 복구를 위한 디자인
오류가 발생하면 자체 복구되도록 애플리케이션 디자인
오류가 분산 시스템에서 발생해야 합니다. 하드웨어가 실패할 수 있습니다. 일시적인 네트워크 오류가 발생할 수 있습니다. 워크로드 아키텍처에서 설계해야 하며, 이는 전체 서비스, 데이터 센터 또는 Azure 지역에서 중단이 발생하는 경우가 거의 없기 때문입니다. 워크로드 디자인 초기에 복원력 및 복구를 해결해야 합니다.
그러므로, 애플리케이션을 오류가 발생하면 자체 복구되도록 디자인합니다. 이를 위해서는 세 가지 방법이 필요합니다.
- 오류 검색
- 오류에 대한 적절한 응답
- 실패 기록 및 모니터링으로 운영 인사이트 제공
애플리케이션의 가용성 요구 사항에 따라 특정 유형의 실패에 대응하는 방법이 달라질 수 있습니다. 예를 들어, 고가용성이 필요한 경우에는 하나의 하위 지역의 여러 가용성 영역에 배포 가능합니다. 중단 방지를 위해, 전체 Azure 지역에서 중단이 발생하는 드문 경우에도 지역 가동 중단 중에 보조 지역으로 자동으로 장애 조치를 수행 가능합니다. 하지만 이러한 경우 단일 지역 배포보다 비용이 더욱 소비되며 잠재적으로 낮은 성능을 유발합니다.
또한 일반적으로 지역 가동 중단과 같이 발생 빈도가 적은 대규모 이벤트는 고려하지 마세요. 네트워크 연결 실패 또는 데이터베이스 연결 실패와 같이 단시간 발생하는 로컬 오류를 처리하는 데 많은 노력을 기울여야 합니다.
권장 사항
비동기적으로 통신하는 분리된 구성 요소를 사용합니다. 이상적으로, 시간 및 공간 측면에서 구성 요소가 분리됩니다. 시간의 분리는 구성 요소가 통신이 가능하기 위해 동시에 존재할 필요가 없음을 나타냅니다. 공간의 분리는 동일한 프로세스에서 발신자와 수신자가 실행할 필요는 없지만, 보다 효율적인 곳이라면 어디든 실행할 수 있다는 것을 나타냅니다. 분리된 구성 요소는 서로 통신하기 위해 이벤트를 사용하는 것이 이상적입니다. 이를 통해 연속 오류의 발생 가능성을 최소화할 수 있습니다.
실패한 작업 다시 시도. 서비스 사용량이 많은 경우, 일시적인 네트워크 연결 해제, 데이터베이스 연결 끊김 또는 시간 제한으로 인한 일시적 오류가 발생할 수도 있습니다. 애플리케이션에 재시도 논리를 작성하여 일시적인 오류를 처리합니다. 많은 Azure 서비스의 경우 클라이언트 SDK는 자동 재시도를 구현합니다. 자세한 내용은 일시적인 오류 처리 및 재시도 패턴을 참조하세요.
실패한 원격 서비스 보호(회로 차단기). 일시적인 오류가 발생하면 다시 시도해 보는 것이 좋지만 오류가 지속되면 많은 호출자에 대한 서비스가 실패할 수 있습니다. 요청이 다시 실행되는 경우, 연속 실패가 발생할 수 있습니다. 작업이 실패할 것 같으면 회로 차단기 패턴을 사용하여(원격 호출을 사용하지 않고) 페일 패스트합니다.
중요한 리소스 격리(격벽). 하나의 하위 시스템에서 발생한 오류가 다른 시스템으로 전이될 수 있습니다. 이와 같은 상황은 오류가 스레드 또는 소켓 같은 리소스를 적시에 놓아주지 않으면 리소스가 고갈됨에 따라 발생될 수 있습니다. 한 파티션의 오류 때문에 전체 시스템이 중단되는 일이 없도록 격벽 패턴을 사용하여 시스템을 격리된 그룹으로 분할함으로써 이러한 상황을 방지합니다.
부하 평준화 수행. 애플리케이션의 트래픽은 백 엔드의 서비스가 감당할 수 없을 정도로 갑자기 치솟을 수도 있습니다. 이를 방지하려면 큐 기반 부하 평준화 패턴을 사용하여 작업 항목을 비동기적으로 실행하도록 큐에 넣습니다. 큐는 피크 부하를 매끄럽게 하는 버퍼 역할을 합니다.
장애 조치(failover). 인스턴스에 연결할 수 없으면 다른 인스턴스로 장애 조치(failover)합니다. 웹 서버와 같이 상태 비저장 항목의 경우 부하 분산 장치 또는 Traffic Manager 뒤에 여러 인스턴스를 배치합니다. 데이터베이스와 같이 상태 저장 항목의 경우 복제본을 사용하여 장애 조치(failover)합니다. 애플리케이션에서 데이터 저장소 및 복제 방법에 따라 최종 일관성을 처리해야 할 수도 있습니다.
실패한 트랜잭션 보정. 일반적으로 분산 트랜잭션은 서비스와 자원 간의 조정이 필요하므로 사용하지 않는 것이 좋습니다. 대신 작은 개별 트랜잭션에서 작업을 구성합니다. 작업이 중간에 실패하면 트랜잭션 보정을 사용하여 이미 완료된 단계를 실행 취소합니다.
장기 실행 트랜잭션의 검사점. 검사점은 장기 실행 작업이 실패할 경우 복원 지점을 제공할 수 있습니다. 작업이 다시 시작되면(예: 다른 VM에서 작업을 시작한 경우) 마지막 검사점에서 작업을 다시 시작할 수 있습니다. 정기적으로 작업에 관한 상태 정보를 기록하고 이 상태를 작업을 실행하는 프로세스의 모든 인스턴스에서 액세스할 수 있는 영구 스토리지에 저장하는 메커니즘 구현을 고려합니다. 이러한 방식으로 프로세스가 종료된 경우 다른 인스턴스를 사용하여 마지막 검사점에서 수행하던 작업을 다시 시작할 수 있습니다. NServiceBus 및 MassTransit와 같은 이 기능을 제공하는 라이브러리가 있습니다. 간격이 Azure Service Bus 큐의 메시지 처리와 일치하는 상태를 투명하게 유지합니다.
응답성은 정상적으로 성능이 저하되고 실패하는 동안 유지됩니다. 경우에 따라 문제를 해결할 수 없지만 여전히 유용한 축소된 기능을 제공할 수는 있습니다. 책 카탈로그를 표시하는 애플리케이션을 생각해 보세요. 이 애플리케이션은 표지의 썸네일 이미지를 검색할 수 없으면 자리 표시자 이미지를 표시할 것입니다. 전체 하위 시스템은 애플리케이션에 중요하지 않을 수 있습니다. 예를 들어, 제품 권장 사항을 보여주는 것은 전자상거래 사이트에서 주문 처리보다 덜 중요합니다.
클라이언트 제한. 때로는 소수의 사용자가 과도한 로드를 생성하여 다른 사용자의 애플리케이션 가용성에 영향을 줄 수 있습니다. 이 경우 특정 시간 동안 클라이언트를 제한합니다. 제한 패턴을 참조하세요.
불량 작업자 차단. 클라이언트를 제한한다고 해서 해당 클라이언트의 작업이 악의적이라는 것을 의미하지는 않습니다. 단지 해당 클라이언트가 서비스 할당량을 초과했다는 것을 의미합니다. 그러나 클라이언트가 지속적으로 할당량을 초과하거나 잘못 작동하면 해당 클라이언트를 차단할 수 있습니다. 사용자가 차단 해제를 요청할 수 있도록 대역 외 프로세스를 정의합니다.
리더 선택 사용. 작업을 조정해야 할 경우 리더 선택을 사용하여 코디네이터를 선택합니다. 이 경우 코디네이터는 단일 실패 지점이 아닙니다. 한 코디네이터가 실패하면 새 코디네이터가 선택됩니다. 리더 선택 알고리즘을 처음부터 구현하는 대신 Zookeeper와 같은 상업용 솔루션을 사용할 수 있습니다.
오류 주입으로 테스트. 성공 경로는 대부분 올바르게 테스트되지만 실패 경로는 그렇지 않은 경우가 많이 있습니다. 시스템은 실패 경로가 실행되기 전에 오랜 시간 동안 프로덕션 환경에서 작동되었을 수 있습니다. 오류 주입을 통해 실제 오류를 트리거하거나 시뮬레이트하여 오류 시 시스템 복원력을 테스트합니다.
비정상 상황 엔지니어링 사용. 비정상 상황 엔지니어링은 오류 주입의 개념을 확장하기 위해 실패 또는 비정상 상황을 무작위로 프로덕션 인스턴스에 주입합니다.
가용성 영역을 사용합니다. 많은 Azure 지역은 해당 하위 지역 내에서 데이터 센터의 격리된 집합인 가용성 영역을 제공합니다. 일부 Azure 서비스를 영역별로 배포하여 특정 영역에 배치하며 동일한 워크로드의 구성 요소 간 통신 대기 시간을 줄일 수 있습니다. 또는 영역 중복으로 일부 서비스를 배포할 수 있으며, 이는 고가용성을 위해 Azure가 영역 간에 리소스를 자동으로 복제한다는 것을 의미합니다. 솔루션에 가장 적합한 절충안 집합을 제공하는 방법이 무엇일지 고려합니다. 가용성 영역 및 지역 사용에 대한 권장 사항을 참조하여 가용성 영역 및 지역을 사용하도록 솔루션을 설계하는 방법에 대한 자세한 내용을 확인하세요.
애플리케이션 자동 복구를 위한 구조화된 접근 방식은 신뢰할 수 있는 Azure용 애플리케이션 디자인을 참조하세요.