Reliable Services 수명 주기 개요

Azure Service Fabric Reliable Services의 수명 주기를 고려할 때 수명 주기의 기본 사항이 가장 중요합니다. 일반적으로 수명 주기에는 다음이 포함됩니다.

  • 시작하는 동안:
    • 서비스가 생성됩니다.
    • 해당 서비스는 0개 이상의 수신기를 생성하고 반환할 수 있습니다.
    • 반환된 모든 수신기 열리면 서비스와의 통신이 가능합니다.
    • 서비스의 RunAsync 메서드가 호출되어 서비스에서 장기 실행 작업 또는 백그라운드 작업을 수행할 수 있습니다.
  • 종료 중:
    • RunAsync에 전달된 취소 토큰이 취소되고 수신기가 닫힙니다.
    • 수신기가 닫히면 서비스 개체 자체가 소멸됩니다.

이러한 이벤트의 정확한 순서에 대한 세부 정보가 있습니다. 이벤트의 순서는 Reliable Service가 상태 비저장인지 또는 상태 저장인지에 따라 약간 변경될 수 있습니다. 또한 상태 저장 서비스의 경우 주 복제본 교환 시나리오를 처리해야 합니다. 이 시퀀스 중, 주 복제본의 역할은 서비스를 종료하지 않으면서 또 다른 복제본으로 전송되거나 다시 돌아옵니다. 마지막으로 오류 또는 오류 조건에 대해 생각해야 합니다.

상태 비저장 서비스 시작

무상태 서비스의 수명 주기는 간단합니다. 이벤트의 순서는 다음과 같습니다.

  1. 서비스가 생성됩니다.
  2. StatelessService.CreateServiceInstanceListeners() 가 호출되고 반환된 모든 수신기가 열립니다. ICommunicationListener.OpenAsync() 는 각 수신기에서 호출됩니다.
  3. 그런 다음, 병렬로 두 가지가 발생합니다.
    • 서비스의 StatelessService.RunAsync() 메서드가 호출됩니다.
    • 있는 경우 서비스의 StatelessService.OnOpenAsync() 메서드가 호출됩니다. 이 호출은 드문 오버라이드이지만 사용할 수 있습니다. 현재 확장 서비스 초기화 작업을 시작할 수 있습니다.

상태 비저장 서비스 종료

상태가 없는 서비스를 종료하는 경우 동일한 패턴을 역순으로 따라야 합니다.

  1. 열려 있는 모든 수신기가 닫힙니다. ICommunicationListener.CloseAsync() 는 각 수신기에서 호출됩니다.
  2. 전달된 RunAsync() 취소 토큰이 취소됩니다. 취소 토큰의 IsCancellationRequested 속성 검사는 true를 반환하고, 호출되는 경우 토큰의 ThrowIfCancellationRequested 메서드가 OperationCanceledException을(를) throw합니다. Service Fabric이 RunAsync()을 완료하기를 기다립니다.
  3. RunAsync() 완료되면 서비스의 StatelessService.OnCloseAsync() 메서드가 호출됩니다(있는 경우). 상태 저장소 없는 서비스 인스턴스가 우아하게 종료될 때 OnCloseAsync가 호출됩니다. 이 문제는 서비스의 코드가 업그레이드되거나, 부하 분산으로 인해 서비스 인스턴스가 이동되거나, 일시적인 오류가 검색될 때 발생할 수 있습니다. StatelessService.OnCloseAsync()을(를) 재정의하는 일은 드물지만, 리소스를 안전하게 닫거나, 백그라운드 처리를 중지하거나, 외부 상태 저장을 완료하거나, 기존 연결을 종료하는 데 사용할 수 있습니다.
  4. StatelessService.OnCloseAsync() 완료되면 서비스 개체가 소멸됩니다.

상태 저장 서비스 시작

상태 저장 서비스는 상태 비저장 서비스와 패턴이 유사하지만, 몇 가지 차이점이 있습니다. 상태 저장 서비스 시작 시 이벤트의 순서는 다음과 같습니다.

  1. 서비스가 생성됩니다.

  2. StatefulServiceBase.OnOpenAsync()을 호출합니다. 일반적으로 해당 호출은 서비스에서 재정의되지 않습니다.

  3. StatefulServiceBase.CreateServiceReplicaListeners() 호출됩니다.

    • 서비스가 기본 서비스인 경우 반환된 모든 수신기가 열립니다. ICommunicationListener.OpenAsync() 는 각 수신기에서 호출됩니다.
    • 서비스가 보조 서비스인 경우, ListenOnSecondary = true으로 표시된 수신기만 열립니다. 보조 시스템에서 수신기를 활성화하는 것은 흔하지 않습니다.
  4. 그런 다음 병렬로 다음을 수행합니다.

    • 서비스가 현재 주 서비스인 경우 서비스의 StatefulServiceBase.RunAsync() 메서드가 호출됩니다.
    • StatefulServiceBase.OnChangeRoleAsync()을 호출합니다. 일반적으로 해당 호출은 서비스에서 재정의되지 않습니다.

    메모

    새 보조 복제본 StatefulServiceBase.OnChangeRoleAsync() 의 경우 두 번 호출됩니다. 2단계 이후 한 번, 유휴 보조가 되면 4단계에서 다시 활성 보조가 됩니다. 복제본 및 인스턴스 수명 주기에 대한 자세한 내용은 복제본 및 인스턴스 수명 주기를 참조하세요.

상태 저장 서비스 종료

무상태 서비스와 마찬가지로, 종료 시의 수명 주기 이벤트는 시작 시와 동일하지만 역순으로 진행됩니다. 상태 저장 서비스를 종료할 때, 다음 이벤트가 발생합니다.

  1. 열려 있는 모든 수신기가 닫힙니다. ICommunicationListener.CloseAsync() 는 각 수신기에서 호출됩니다.

  2. StatefulServiceBase.OnCloseAsync() 메서드가 호출됩니다. 이 호출은 드물게 발생하는 무시 옵션이지만 사용할 수 있습니다.

  3. 전달된 RunAsync() 취소 토큰이 취소됩니다. 취소 토큰의 IsCancellationRequested 속성 검사는 true를 반환하고, 호출되는 경우 토큰의 ThrowIfCancellationRequested 메서드가 OperationCanceledException을(를) throw합니다. Service Fabric이 RunAsync()을 완료하기를 기다립니다.

    메모

    이 복제본이 주 복제본인 경우에만 RunAsync 가 완료되기를 기다려야 합니다.

  4. StatefulServiceBase.RunAsync() 완료되면 서비스 개체가 소멸됩니다.

상태 저장 서비스 주 교환

상태 저장 서비스가 실행되는 동안 해당 상태 저장 서비스의 주 복제본만 통신 수신기를 열고 RunAsync 메서드를 호출합니다. 보조 레플리카가 생성되지만 더 이상 호출되지 않습니다. 현재 주 복제본인 복제본은 상태 저장 서비스가 실행되는 동안 오류 또는 클러스터 분산 최적화의 결과로 변경될 수 있습니다. 복제본에서 볼 수 있는 수명 주기 이벤트의 측면에서 이 의미는 무엇인가요? 교환 중에 강등되거나 승격되는 복제본인지 여부에 따라 상태 저장 복제본이 보는 동작이 달라집니다.

강등되는 주 복제본의 경우

강등된 주 복제본의 경우 Service Fabric은 메시지 처리를 중지하고 수행 중인 백그라운드 작업을 종료하려면 이 복제본이 필요합니다. 결과적으로 이 단계는 서비스가 종료될 때와 같습니다. 한 가지 차이점은 서비스가 보조 서비스로 남아 있기 때문에 소멸되거나 닫혀 있지 않다는 것입니다. 다음 API가 호출됩니다.

  1. 열려 있는 모든 수신기가 닫힙니다. ICommunicationListener.CloseAsync() 는 각 수신기에서 호출됩니다.
  2. 전달된 RunAsync() 취소 토큰이 취소됩니다. 취소 토큰의 IsCancellationRequested 속성 검사는 true를 반환하고, 호출되는 경우 토큰의 ThrowIfCancellationRequested 메서드가 OperationCanceledException을(를) throw합니다. Service Fabric이 RunAsync()을 완료하기를 기다립니다.
  3. ListenOnSecondary = true로 표시된 수신기가 열립니다.
  4. 서비스가 StatefulServiceBase.OnChangeRoleAsync() 호출됩니다. 일반적으로 해당 호출은 서비스에서 재정의되지 않습니다.

승격된 보조 복제본의 경우

이와 유사하게, Service Fabric에서 승격된 보조 복제본은 네트워크에서 메시지 수신을 시작하고 필요한 모든 백그라운드 작업을 시작해야 합니다. 결과적으로 이 프로세스는 복제본 자체가 이미 존재한다는 점을 제외하고 서비스를 만들 때와 같습니다. 다음 API가 호출됩니다.

  1. ICommunicationListener.CloseAsync() 는 열려 있는 모든 수신기에 대해 호출됩니다(ListenOnSecondary = true로 표시됨).
  2. 모든 통신 수신기가 열립니다. ICommunicationListener.OpenAsync() 는 각 수신기에서 호출됩니다.
  3. 그런 다음 병렬로 다음을 수행합니다.
    • 서비스의 StatefulServiceBase.RunAsync() 메서드가 호출됩니다.
    • StatefulServiceBase.OnChangeRoleAsync()을 호출합니다. 일반적으로 해당 호출은 서비스에서 재정의되지 않습니다.

메모

CreateServiceReplicaListeners 는 한 번만 호출되며 복제본 승격 또는 강등 프로세스 중에 다시 호출되지 않습니다. 동일한 ServiceReplicaListener 인스턴스가 사용되지만 이전 인스턴스가 닫힌 후 새 ICommunicationListener 인스턴스가 만들어집니다(메서드를 호출 ServiceReplicaListener.CreateCommunicationListener 하여).

상태 저장 서비스 종료 및 기본 수준 내리기 동안의 일반적인 문제

다양한 이유로 Service Fabric은 상태 저장 서비스의 기본 서비스를 바꿉니다. 가장 일반적인 것은 클러스터 리밸런싱애플리케이션 업그레이드입니다. 이러한 작업 중(예를 들어 서비스가 삭제된 경우와 같은 일반적인 서비스 종료 시) 서비스가 CancellationToken을 준수하는 것이 중요합니다.

취소를 깔끔하게 처리하지 않는 서비스에는 몇 가지 문제가 발생할 수 있습니다. Service Fabric은 서비스가 정상적으로 중지될 때까지 대기하므로 이러한 작업이 느립니다. 그 결과, 궁극적으로 시간이 초과되며 롤백되는 업그레이드가 실패하게 될 수 있습니다. 취소 토큰을 적용하지 못하면 클러스터가 불균형해질 수도 있습니다. 노드가 뜨거워지므로 클러스터의 불균형이 되지만 다른 곳으로 이동하는 데 너무 오래 걸리므로 서비스의 균형을 조정할 수 없습니다.

서비스는 상태 저장이므로 신뢰할 수 있는 컬렉션을 사용할 수도 있습니다. Service Fabric에서 주 복제본이 강등될 때 가장 먼저 발생하는 상황 중 하나는 기본 상태에 대한 쓰기 액세스가 철회된다는 것입니다. 이로 인해 서비스 수명 주기에 영향을 줄 수 있는 두 번째 문제 집합이 발생합니다. 컬렉션은 타이밍 및 복제본이 이동 또는 종료되는지 여부에 따라 예외를 반환합니다. 이러한 예외는 올바르게 처리되어야 합니다. Service Fabric에서 throw된 예외는 영구(FabricException) 및 일시적(FabricTransientException) 범주에 분류됩니다. 영구 예외는 기록되고 던져져야 하며, 일시적 예외는 특정 재시도 로직에 따라 다시 시도할 수 있습니다.

서비스 수명 주기 이벤트와 함께 사용 ReliableCollections 에서 발생하는 예외를 처리하는 것은 신뢰할 수 있는 서비스를 테스트하고 유효성을 검사하는 데 중요한 부분입니다. 프로덕션 환경에 배포하기 전에 업그레이드 및 비정상 상황 테스트를 수행하는 동안 항상 부하 상태에서 서비스를 실행하는 것이 좋습니다. 이러한 기본 단계는 서비스가 올바르게 구현되고 수명 주기 이벤트를 올바르게 처리하는 데 도움이 됩니다.

서비스 수명 주기에 대한 참고 사항

  • RunAsync() 메서드와 CreateServiceReplicaListeners/CreateServiceInstanceListeners 호출들은 모두 선택사항입니다. 서비스에는 하나 있을 수도 있고, 둘 다 있을 수도 있으며, 둘 다 없을 수도 있습니다. 예를 들어 서비스가 사용자 호출에 대한 응답으로 모든 작업을 수행하는 경우 구현 RunAsync()할 필요가 없습니다. 통신 수신기 및 관련 코드만 필요합니다. 마찬가지로, 통신 수신기를 만들고 반환하는 것은 선택 사항입니다. 서비스에는 백그라운드 작업만 있을 수 있으므로 구현 RunAsync()하기만 하면 됩니다.
  • 서비스가 RunAsync()을(를) 성공적으로 완료하고 여기에서 반환하는 것은 유효합니다. 완료는 실패 조건이 아닙니다. 완료 RunAsync() 는 서비스의 백그라운드 작업이 완료되었음을 나타냅니다. 상태 저장 신뢰할 수 있는 서비스의 경우 복제본이 주에서 보조로 강등된 다음 다시 주로 승격되면 RunAsync()가 다시 호출됩니다.
  • 서비스가 RunAsync()에서 예기치 않은 예외를 발생시켜 종료될 경우, 이는 오류로 간주됩니다. 서비스 개체가 종료되고 상태 오류가 보고됩니다.
  • 이러한 메서드에서 반환하는 데 시간 제한은 없지만 신뢰할 수 있는 컬렉션에 쓸 수 있는 기능이 즉시 손실되므로 실제 작업을 완료할 수 없습니다. 취소 요청을 받으면 최대한 빨리 반환하는 것이 좋습니다. 서비스가 적절한 시간 내에 이러한 API 호출에 응답하지 않는 경우 Service Fabric은 서비스를 강제로 종료할 수 있습니다. 일반적으로 이 작업은 애플리케이션 업그레이드 중 또는 서비스가 삭제되는 경우에만 발생합니다. 이 시간 제한은 기본적으로 15분입니다.
  • 경로의 OnCloseAsync() 실패로 인해 OnAbort() 호출됩니다. 이는 서비스가 요청한 리소스를 정리하고 해제할 수 있는 마지막 기회입니다. 이는 일반적으로 노드에서 영구 오류가 감지되거나 서비스 패브릭이 내부 오류로 인해 서비스 인스턴스의 수명 주기를 안정적으로 관리할 수 없는 경우에 호출됩니다.
  • OnChangeRoleAsync()는 상태 저장 서비스 복제본이 주 또는 보조 역할로 변경될 때 호출됩니다. 주 복제본에는 쓰기 상태가 지정됩니다(신뢰할 수 있는 컬렉션을 만들고 쓸 수 있습니다). 보조 복제본에는 읽기 상태가 지정됩니다(기존 신뢰할 수 있는 컬렉션에서만 읽을 수 있음). 상태 저장 서비스에서 대부분의 작업은 주 복제본에서 수행됩니다. 보조 복제본은 읽기 전용 유효성 검사, 보고서 생성, 데이터 마이닝 또는 기타 읽기 전용 작업을 수행할 수 있습니다.

다음 단계