자체 복구를 위한 디자인

오류가 발생하면 자체 복구되도록 애플리케이션 디자인

분산 시스템에서는 오류가 발생할 수 있습니다. 하드웨어가 실패할 수 있습니다. 일시적인 네트워크 오류가 발생할 수 있습니다. 전체 서비스, 데이터 센터 또는 Azure 지역에서 중단이 발생하는 경우는 거의 없습니다. 그러나 이러한 서비스도 계획해야 합니다.

따라서 오류가 발생할 때 자체 복구되는 애플리케이션을 디자인합니다. 이를 위해서는 세 가지 방법이 필요합니다.

  • 오류 검색
  • 오류에 대한 적절한 응답
  • 오류를 기록하고 모니터링하여 운영 인사이트를 제공합니다.

특정 유형의 실패에 대응하는 방법은 애플리케이션의 가용성 요구 사항에 따라 달라질 수 있습니다. 예를 들어 고가용성이 필요한 경우 한 지역의 여러 가용성 영역에 배포할 수 있습니다. 중단을 방지하기 위해 전체 Azure 지역에서 중단이 발생하는 드문 경우에도 지역 가동 중단 중에 보조 지역으로 자동으로 장애 조치(failover)할 수 있습니다. 그러나 단일 지역 배포보다 비용이 더 높고 성능이 저하될 수 있습니다.

또한 일반적으로 지역 가동 중단과 같이 발생 빈도가 적은 대규모 이벤트는 고려하지 마세요. 네트워크 연결 실패 또는 데이터베이스 연결 실패와 같이 단시간 발생하는 로컬 오류를 처리하는 데 많은 노력을 기울여야 합니다.

권장 사항

실패한 작업 다시 시도. 서비스 사용량이 많을 때 일시적인 네트워크 연결 해제, 데이터베이스 연결 끊김 또는 시간 제한으로 인해 일시적 오류가 발생할 수 있습니다. 애플리케이션에 재시도 논리를 작성하여 일시적인 오류를 처리합니다. 많은 Azure 서비스의 경우 클라이언트 SDK는 자동 재시도를 구현합니다. 자세한 내용은 일시적인 오류 처리재시도 패턴을 참조하세요.

실패한 원격 서비스 보호(회로 차단기). 일시적인 오류가 발생하면 다시 시도해 보는 것이 좋지만 오류가 지속되면 많은 호출자에 대한 서비스가 실패할 수 있습니다. 이로 인해 요청이 백업됨에 따라 연속 실패가 발생할 수 있습니다. 작업이 실패할 것 같으면 회로 차단기 패턴을 사용하여(원격 호출을 사용하지 않고) 페일 패스트합니다.

중요한 리소스 격리(격벽). 하나의 하위 시스템에서 발생한 오류가 다른 시스템으로 전이될 수 있습니다. 이 오류로 인해 스레드 또는 소켓과 같은 일부 리소스가 적시에 해제되지 않아 리소스 소모가 발생할 수 있습니다. 이를 방지하려면 Bulkhead 패턴을 사용하여 시스템을 격리된 그룹으로 분할하여 하나의 파티션에서 오류가 발생해도 전체 시스템이 중단되지 않도록 합니다.

부하 평준화 수행. 백 엔드의 서비스가 감당할 수 없을 정도로 애플리케이션의 트래픽이 갑자기 치솟을 수 있습니다. 이를 방지하려면 큐 기반 부하 평준화 패턴을 사용하여 작업 항목을 비동기적으로 실행하도록 큐에 넣습니다. 큐는 피크 부하를 매끄럽게 하는 버퍼 역할을 합니다.

장애 조치(failover). 인스턴스에 연결할 수 없으면 다른 인스턴스로 장애 조치(failover)합니다. 웹 서버와 같이 상태 비저장 항목의 경우 부하 분산 장치 또는 Traffic Manager 뒤에 여러 인스턴스를 배치합니다. 데이터베이스와 같이 상태 저장 항목의 경우 복제본을 사용하여 장애 조치(failover)합니다. 데이터 저장소 및 데이터 저장소가 복제본(replica) 방법에 따라 애플리케이션은 최종 일관성을 처리해야 할 수 있습니다.

실패한 트랜잭션 보정. 일반적으로 분산 트랜잭션은 서비스와 자원 간의 조정이 필요하므로 사용하지 않는 것이 좋습니다. 대신 작은 개별 트랜잭션에서 작업을 구성합니다. 작업이 중간에 실패하면 트랜잭션 보정을 사용하여 이미 완료된 단계를 실행 취소합니다.

장기 실행 트랜잭션의 검사점. 검사점은 장기 실행 작업이 실패할 경우 복원 지점을 제공할 수 있습니다. 작업이 다시 시작되면(예: 다른 VM에서 작업을 시작한 경우) 마지막 검사점에서 작업을 다시 시작할 수 있습니다. 정기적으로 작업에 관한 상태 정보를 기록하고 이 상태를 작업을 실행하는 프로세스의 모든 인스턴스에서 액세스할 수 있는 영구 스토리지에 저장하는 메커니즘 구현을 고려합니다. 이러한 방식으로 프로세스가 종료된 경우 다른 인스턴스를 사용하여 마지막 검사점에서 수행하던 작업을 다시 시작할 수 있습니다. NServiceBusMassTransit와 같은 이 기능을 제공하는 라이브러리가 있습니다. 간격이 Azure Service Bus 큐의 메시지 처리와 일치하는 상태를 투명하게 유지합니다.

정상적으로 성능 저하. 경우에 따라 문제를 해결할 수 없지만 여전히 유용한 축소된 기능을 제공할 수는 있습니다. 책 카탈로그를 표시하는 애플리케이션을 생각해 보세요. 이 애플리케이션은 표지의 썸네일 이미지를 검색할 수 없으면 자리 표시자 이미지를 표시할 것입니다. 전체 하위 시스템은 애플리케이션에 중요하지 않을 수 있습니다. 예를 들어 전자 상거래 사이트에서 제품 권장 사항을 표시하는 것은 주문을 처리하는 것보다 덜 중요할 수 있습니다.

클라이언트 제한. 때로는 소수의 사용자가 과도한 로드를 생성하여 다른 사용자의 애플리케이션 가용성에 영향을 줄 수 있습니다. 이 경우 특정 시간 동안 클라이언트를 제한합니다. 제한 패턴을 참조하세요.

불량 작업자 차단. 클라이언트를 제한한다고 해서 해당 클라이언트의 작업이 악의적이라는 것을 의미하지는 않습니다. 단지 해당 클라이언트가 서비스 할당량을 초과했다는 것을 의미합니다. 그러나 클라이언트가 지속적으로 할당량을 초과하거나 잘못 작동하면 해당 클라이언트를 차단할 수 있습니다. 사용자가 차단 해제를 요청할 수 있도록 대역 외 프로세스를 정의합니다.

리더 선택 사용. 작업을 조정해야 할 경우 리더 선택을 사용하여 코디네이터를 선택합니다. 이 경우 코디네이터는 단일 실패 지점이 아닙니다. 한 코디네이터가 실패하면 새 코디네이터가 선택됩니다. 리더 선택 알고리즘을 처음부터 구현하는 대신 Zookeeper와 같은 상업용 솔루션을 사용할 수 있습니다.

오류 주입으로 테스트. 성공 경로는 대부분 올바르게 테스트되지만 실패 경로는 그렇지 않은 경우가 많이 있습니다. 시스템은 실패 경로가 실행되기 전에 오랜 시간 동안 프로덕션 환경에서 작동되었을 수 있습니다. 오류 주입을 통해 실제 오류를 트리거하거나 시뮬레이트하여 오류 시 시스템 복원력을 테스트합니다.

비정상 상황 엔지니어링 사용. 비정상 상황 엔지니어링은 오류 또는 비정상적인 조건을 프로덕션 인스턴스에 임의로 주입하여 오류 주입 개념을 확장합니다.

가용성 영역을 사용하는 것이 좋습니다. 많은 Azure 지역은 지역 내에서 격리된 데이터 센터 집합인 가용성 영역을 제공합니다. 일부 Azure 서비스를 영역별로 배포하여 특정 영역에 배치하고 동일한 워크로드의 구성 요소 간 통신 대기 시간을 줄일 수 있습니다. 또는 일부 서비스는 영역 중복성을 사용하여 배포할 수 있습니다. 즉, Azure는 고가용성을 위해 영역 간에 리소스를 자동으로 복제본(replica). 솔루션에 가장 적합한 절충안 집합을 제공하는 방법을 고려합니다. 가용성 영역 및 지역을 사용하도록 솔루션을 디자인하는 방법에 대한 자세한 내용은 가용성 영역 및 지역 사용에 대한 권장 사항 참조하세요.

애플리케이션 자동 복구를 위한 구조화된 접근 방식은 신뢰할 수 있는 Azure용 애플리케이션 디자인을 참조하세요.