Reliable Services 수명 주기 개요
Azure Service Fabric Reliable Services의 수명 주기를 고려할 경우 수명 주기에 대한 기본 사항이 가장 중요합니다. 일반적으로 수명 주기는 다음과 같습니다.
- 시작 중:
- 서비스가 생성됩니다.
- 서비스는 0개 이상의 수신기를 생성하고 반환할 수 있습니다.
- 반환된 모든 수신기가 열리면 서비스와의 통신이 가능합니다.
- 서비스의 RunAsync 메서드를 호출하면 서비스가 장기 실행 중인 작업 또는 백그라운드 작업을 수행할 수 있습니다.
- 종료 중:
- RunAsync에 전달된 취소 토큰이 취소되고 수신기 닫힙니다.
- 수신기가 닫히면 서비스 개체 자체는 소멸됩니다.
이러한 이벤트의 정확한 순서에 대한 세부 정보가 있습니다. 이벤트의 순서는 Reliable Service가 상태 비저장인지 또는 상태 저장인지에 따라 약간 변경될 수 있습니다. 또한 상태 저장 서비스의 경우 주 복제본 교환 시나리오를 처리해야 합니다. 이 과정 중에 서비스를 종료하지 않고 주 복제본의 역할을 다른 복제본으로 전송하거나 복구합니다. 마지막으로 오류 또는 실패 조건에 대해 고려해야 합니다.
상태 비저장 서비스 시작
상태 비저장 서비스의 수명 주기는 간단합니다. 이벤트의 순서는 다음과 같습니다.
- 서비스가 생성됩니다.
StatelessService.CreateServiceInstanceListeners()
가 호출되고 반환된 모든 수신기가 열립니다.ICommunicationListener.OpenAsync()
가 각 수신기에서 호출됩니다.- 그런 후 다음 두 가지 작업이 동시에 수행됩니다.
- 서비스의
StatelessService.RunAsync()
메서드가 호출됩니다. - 있는 경우 서비스의
StatelessService.OnOpenAsync()
메서드가 호출됩니다. 이 호출은 일반적이지 않은 재정의이지만 사용 가능합니다. 이때 확장된 서비스 초기화 작업을 시작할 수 있습니다.
- 서비스의
상태 비저장 서비스 종료
상태 비저장 서비스를 종료할 경우 동일한 패턴이 역방향으로 다음과 같이 따라옵니다.
- 열려 있는 수신기가 모두 닫힙니다.
ICommunicationListener.CloseAsync()
가 각 수신기에서 호출됩니다. RunAsync()
에 전달된 취소 토큰이 취소됩니다. 취소 토큰의IsCancellationRequested
속성을 확인하면 true를 반환하고, 호출되는 경우 토큰의ThrowIfCancellationRequested
메서드에서OperationCanceledException
이 발생됩니다. Service Fabric은RunAsync()
가 완료되기를 기다립니다.RunAsync()
가 완료된 후 서비스의StatelessService.OnCloseAsync()
메서드가 호출됩니다(제공된 경우). 상태 비저장 서비스 인스턴스가 정상적으로 종료되려고 할 때 OnCloseAsync가 호출됩니다. 이는 서비스의 코드를 업그레이드할 때, 로드 균형 조정으로 인해 서비스 인스턴스가 이동할 때 또는 일시적인 오류가 감지되었을 때 발생할 수 있습니다.StatelessService.OnCloseAsync()
재정의는 일반적이지 않지만 리소스를 안전하게 닫거나 백그라운드 프로세스를 중지하거나 외부 상태 저장을 완료하거나 기존 연결을 종료하는 데 사용할 수 있습니다.StatelessService.OnCloseAsync()
이 완료되면 서비스 개체는 소멸됩니다.
상태 저장 서비스 시작
상태 저장 서비스는 몇 가지를 변경한 상태 비저장 서비스 패턴과 비슷합니다. 상태 저장 서비스를 시작하면 이벤트의 순서는 다음과 같습니다.
서비스가 생성됩니다.
StatefulServiceBase.OnOpenAsync()
을 호출합니다. 이 호출은 서비스에서 드물게 재정의됩니다.StatefulServiceBase.CreateServiceReplicaListeners()
가 호출됩니다.- 서비스가 주 서비스인 경우 반환된 모든 수신기가 열립니다.
ICommunicationListener.OpenAsync()
가 각 수신기에서 호출됩니다. - 서비스가 보조 서비스인 경우
ListenOnSecondary = true
로 표시된 수신기만 열립니다. 보조 복제본에서 수신기가 열려 있는 경우는 일반적이지 않습니다.
- 서비스가 주 서비스인 경우 반환된 모든 수신기가 열립니다.
그런 다음, 병렬로:
- 서비스가 현재 주 서비스인 경우 서비스의
StatefulServiceBase.RunAsync()
메서드가 호출됩니다. StatefulServiceBase.OnChangeRoleAsync()
을 호출합니다. 이 호출은 서비스에서 드물게 재정의됩니다.
참고 항목
새 보조 복제본의 경우
StatefulServiceBase.OnChangeRoleAsync()
가 두 번 호출됩니다. 2단계 이후 한 번, 유휴 보조가 되면 4단계에서 다시 활성 보조가 됩니다. 복제본 및 인스턴스 수명 주기에 대한 자세한 내용은 복제본 및 인스턴스 수명 주기를 참조하세요.- 서비스가 현재 주 서비스인 경우 서비스의
상태 저장 서비스 종료
상태 비저장 서비스와 마찬가지로 종료 중 수명 주기 이벤트는 시작 시와 동일하지만 역방향으로 이뤄집니다. 상태 저장 서비스가 종료되면 다음과 같은 이벤트가 발생합니다.
열려 있는 수신기가 모두 닫힙니다.
ICommunicationListener.CloseAsync()
가 각 수신기에서 호출됩니다.StatefulServiceBase.OnCloseAsync()
메서드가 호출됩니다. 이 호출은 일반적이지 않은 재정의이지만 사용 가능합니다.RunAsync()
에 전달된 취소 토큰이 취소됩니다. 취소 토큰의IsCancellationRequested
속성을 확인하면 true를 반환하고, 호출되는 경우 토큰의ThrowIfCancellationRequested
메서드에서OperationCanceledException
이 발생됩니다. Service Fabric은RunAsync()
가 완료되기를 기다립니다.참고 항목
RunAsync가 완료될 때까지 기다려야 하는 경우는 이 복제본이 주 복제본인 경우 뿐입니다.
StatefulServiceBase.RunAsync()
이 완료되면 서비스 개체는 소멸됩니다.
상태 저장 서비스 주 교환
상태 저장 서비스가 실행되는 동안 해당 상태 저장 서비스의 주 복제본은 해당 통신 수신기를 열고 해당 RunAsync 메서드를 호출합니다. 보조 복제본을 생성하지만 더 이상 호출하지 않습니다. 장애 또는 클러스터 균형 조정 최적화의 결과로 상태 저장 서비스가 실행되는 동안 현재 주 복제본인 복제본을 변경할 수 있습니다. 복제본이 확인할 수 있는 수명 주기 이벤트의 측면에서 무슨 의미인가요? 상태 저장 복제본이 확인하는 동작은 강등되는 복제본인지 승격되는 복제본인지에 따라 달라 집니다.
강등되는 주 복제본의 경우
강등되는 주 복제본의 경우 Service Fabric은 이 복제본에서 메시지 처리를 중지하고 수행 중인 모든 백그라운드 작업을 종료하도록 합니다. 결과적으로 이 단계는 서비스가 종료될 경우와 유사합니다. 한 가지 차이점은 서비스가 보조 복제본으로 그대로 남아 있으므로 소멸되거나 종료되지 않는다는 점입니다. 다음 API가 호출됩니다.
- 열려 있는 수신기가 모두 닫힙니다.
ICommunicationListener.CloseAsync()
가 각 수신기에서 호출됩니다. RunAsync()
에 전달된 취소 토큰이 취소됩니다. 취소 토큰의IsCancellationRequested
속성을 확인하면 true를 반환하고, 호출되는 경우 토큰의ThrowIfCancellationRequested
메서드에서OperationCanceledException
이 발생됩니다. Service Fabric은RunAsync()
가 완료되기를 기다립니다.- ListenOnSecondary = true로 표시된 수신기가 열립니다.
- 서비스의
StatefulServiceBase.OnChangeRoleAsync()
가 호출됩니다. 이 호출은 서비스에서 드물게 재정의됩니다.
승격되는 보조 복제본의 경우
마찬가지로 Service Fabric에서 통신 중에 메시지에 대한 수신 대기를 시작하고, 관심 있는 모든 백그라운드 작업을 시작하기 위해 승격되는 보조 복제본이 필요합니다. 결과적으로 이 프로세스는 복제본 자체가 이미 존재한다는 점을 제외하면 서비스를 만들 때와 유사합니다. 다음 API가 호출됩니다.
ICommunicationListener.CloseAsync()
는 열려 있는 모든 수신기에 대해 호출됩니다(ListenOnSecondary = true로 표시됨).- 모든 통신 수신기가 열립니다.
ICommunicationListener.OpenAsync()
가 각 수신기에서 호출됩니다. - 그런 다음, 동시에 다음이 수행됩니다.
- 서비스의
StatefulServiceBase.RunAsync()
메서드가 호출됩니다. StatefulServiceBase.OnChangeRoleAsync()
을 호출합니다. 이 호출은 서비스에서 드물게 재정의됩니다.
- 서비스의
참고 항목
CreateServiceReplicaListeners
는 한 번만 호출되며 복제본 승격 또는 강등 프로세스 중에 다시 호출되지 않습니다. 동일한 ServiceReplicaListener
인스턴스가 사용되지만 이전 인스턴스가 닫힌 후 ServiceReplicaListener.CreateCommunicationListener
메서드를 호출하여 새 ICommunicationListener
인스턴스가 만들어집니다.
상태 저장 서비스 종료 및 기본 수준 내리기 동안의 일반적인 문제
Service Fabric에서는 다양한 이유로 상태 저장 서비스에 대한 주 복제본을 변경합니다. 가장 일반적인 것은 클러스터 재분산 및 애플리케이션 업그레이드입니다. 이러한 작업 동안(서비스가 삭제되었는지 확인하는 경우처럼 정상적인 서비스 종료 동안에도) 서비스에서 CancellationToken
을 준수하는 것이 중요합니다.
취소를 완전히 처리하지 않는 서비스에는 몇 가지 문제가 발생합니다. Service Fabric에서 서비스가 정상적으로 중지되기를 기다리기 때문에 이러한 작업이 느려질 수 있습니다. 이로 인해 궁극적으로 시간이 초과되고 롤백하게 되는 실패한 업그레이드로 이어질 수 있습니다. 취소 토큰을 사용하지 않으면 클러스터가 분산되지 않을 수도 있습니다. 클러스터가 핫 노드가 되어 분산되지 않게 되지만 다른 곳으로 이동하는 데 시간이 너무 오래 걸리므로 서비스를 다시 분산할 수 없습니다.
서비스가 상태 저장 서비스이므로 신뢰할 수 있는 컬렉션을 사용하고 있을 가능성이 큽니다. Service Fabric에서 주 복제본이 강등될 때 가장 먼저 발생하는 상황 중 하나는 기본 상태에 대한 쓰기 액세스가 철회된다는 것입니다. 이로 인해 서비스 수명 주기에 영향을 줄 수 있는 두 번째 문제 집합이 발생합니다. 컬렉션에서는 타이밍 및 복제본이 이동되거나 종료되는지 여부에 따라 예외를 반환합니다. 이러한 예외는 올바르게 처리되어야 합니다. Service Fabric에서 발생한(throw) 예외는 영구(FabricException
) 및 일시적(FabricTransientException
) 범주로 분류됩니다. 영구 예외는 기록되고 발생되어야 하지만, 일시적 예외는 몇 가지 다시 시도 논리에 따라 다시 시도될 수 있습니다.
서비스 수명 주기 이벤트와 함께 ReliableCollections
사용으로 인한 예외 처리는 신뢰할 수 있는 서비스의 테스트 및 유효성 검사에 대한 중요한 부분입니다. 권장 사항은 항상 프로덕션에 배포하기 전에 업그레이드 및 비정상 상황 테스트(chaos testing)를 수행하는 동안 로드 상태에서 서비스를 실행하는 것입니다. 이러한 기본 단계를 통해 서비스가 올바르게 구현되고 수명 주기 이벤트가 올바르게 처리되도록 할 수 있습니다.
서비스 수명 주기에 대한 참고 사항
RunAsync()
메서드 및CreateServiceReplicaListeners/CreateServiceInstanceListeners
호출은 모두 선택 사항입니다. 서비스에는 이러한 항목이 있거나 없을 수도 있습니다. 예를 들어, 서비스가 모든 작업을 사용자 호출에 대한 응답으로 수행할 경우RunAsync()
을(를) 구현할 필요가 없습니다. 통신 수신기 및 해당 관련 코드만이 필요합니다. 마찬가지로 통신 수신기를 만들고 반환하는 작업은 선택적이며 서비스가 백그라운드 작업을 수행해야 하므로RunAsync()
을 구현해야 합니다.- 서비스가
RunAsync()
을 성공적으로 완료하고 거기에서 반환하는 작업이 유효합니다. 완료는 실패 조건이 아닙니다.RunAsync()
를 완료하면 서비스의 백그라운드 작업이 완료되었음을 나타냅니다. 상태 저장 신뢰할 수 있는 서비스의 경우 복제본이 주에서 보조로 강등된 다음 다시 주로 승격되면RunAsync()
가 다시 호출됩니다. - 예기치 않은 예외가 발생(throw)되어 서비스가
RunAsync()
에서 종료되는 경우 실패로 간주됩니다. 서비스 개체가 종료되고 상태 오류가 보고됩니다. - 이러한 메서드에서 반환에는 시간 제한이 없으며 신뢰할 수 있는 컬렉션에 작성할 수 있는 기능이 즉시 손실되고 모든 실제 작업을 완료할 수 없습니다. 취소 요청을 받는 즉시 최대한 신속하게 반환하는 것이 좋습니다. 서비스가 적절한 시간 내에 이러한 API 호출에 응답하지 않으면 Service Fabric은 서비스를 강제로 종료할 수 있습니다. 이러한 상황은 일반적으로 애플리케이션을 업그레이드하거나 서비스를 삭제할 때 발생합니다. 이 시간 제한은 기본적으로 15분입니다.
OnCloseAsync()
경로의 오류로 인해OnAbort()
가 호출되고 이것이 서비스에서 요구하는 리소스를 정리하고 릴리스할 수 있는 마지막 방법입니다. 이는 일반적으로 노드에서 영구 오류가 감지되거나, 내부 오류로 인해 서비스 패브릭에서 서비스 인스턴스 수명 주기를 안정적으로 관리할 수 없을 때 호출됩니다.- 상태 저장 서비스 복제본이 역할을 변경할 경우(예: 주 또는 보조)
OnChangeRoleAsync()
가 호출됩니다. 주 복제본에는 쓰기 상태가 지정됩니다(신뢰할 수 있는 컬렉션을 만들고 쓰도록 허용). 보조 복제본에는 읽기 상태가 지정됩니다(신뢰할 수 있는 기존 컬렉션에서 읽기만 가능). 상태 저장 서비스에서 대부분의 작업은 주 복제본에서 수행됩니다. 보조 복제본은 읽기 전용 유효성 검사, 보고서 생성, 데이터 마이닝 또는 다른 읽기 전용 작업을 수행할 수 있습니다.