2017-01-09 3 views
0

신뢰할 수있는 대기열 (while 루프 내부)에서 데이터를 처리하는 상태 저장 서비스가 있습니다. 데이터 처리는 실제로 상태 비 저장 서비스를 호출합니다.서비스 구조의 상태 저장 서비스에 상태 비 저장 서비스 주입

스테이트리스 서비스가 한 노드에서 다른 노드로 이동할 수 있으므로 상태 저장 서비스의 생성자에이 종속성 (상태 비 저장 서비스)을 주입하는 것이 안전합니까? 생성자에서 초기화/삽입 된 종속성이 하나의 노드로 수정되지 않았는지 확인하기 만하면됩니다.

답변

2

remoting을 사용하여 상태 비 저장 서비스와 통신하는 경우 IServiceProxyFactory을 생성자에 삽입 할 수 있습니다. 이 방법으로 테스트 목적으로 Mock을 주입 할 수도 있습니다.

이 답변 이후 질문이 변경되었습니다. 추가 정보는 : 서비스 원격 서비스 주소 해상도를 처리, 연결, 재시도, 오류 처리

예 :

public class MyStatefulService : StatefulService 
    { 
     private readonly Uri CalledServiceName = new Uri("fabric:/MyApp/MyStatefulService"); 
     private readonly IServiceProxyFactory ServiceProxyFactory; 

     public MyStatefulService(StatefulServiceContext serviceContext, IReliableStateManagerReplica reliableStateManagerReplica, IServiceProxyFactory serviceProxyFactory = null) 
      : base(serviceContext, reliableStateManagerReplica)   
     {  
      ServiceProxyFactory = serviceProxyFactory ?? new ServiceProxyFactory(); 
     } 

     public Task InsertAsync(object value) 
     { 
      var serviceProxy = ServiceProxyFactory.CreateServiceProxy<IMyStatefulService>(CalledServiceName);   
      return serviceProxy.InsertAsync(value); 
     } 
    } 
+0

예. 나는 초기화/호출 :'ServiceProxy.Create (serviceUri)' – alltej

+0

예를 들어 설명해 주시겠습니까? 감사합니다 – alltej

+0

그래, 그게 내가 어디서 오는지 - 테스트 가능성에 대한 의존성을 주입하는 것입니다. 루프 내에서 stateless 서비스를 호출 중이므로 신뢰할 수있는 q의 각 반복에서 해당 서비스를 초기화하거나 발견해야합니다. ueue? 또는 동일한 serviceProxy 인스턴스를 사용하는 것이 안전합니까? 서비스가 노드에서 더 이상 사용할 수없는 경우 SF가 검색을 처리한다는 것을 의미합니다. – alltej

0

TL; DR; 예, 서비스 원격 클라이언트가 대부분의 경우에 해당 시나리오를 처리 할 수 ​​있습니다.

설명 : 서비스 리모컨을 사용하여 서비스와 통신하도록 프록시를 만들면 실제 서비스와의 통신을 다시 시도 할 수있는 클라이언트가됩니다.

해결 및 서비스에 연결하는 루프에서 실행되는 다음 단계가 포함됩니다 :

    을 서비스 검색 및 해상도를 설명합니다 특히 섹션의 설명서 ( https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-connect-and-communicate-with-services)에서이 약 일부 설명이있다
  • 해결 : 서비스가 이름 지정 서비스에서 게시 한 끝점을 가져옵니다.
  • : 해당 끝점에서 사용하는 프로토콜을 통해 서비스에 연결합니다.
  • 다시 시도 : 예를 들어 끝점 주소가 마지막으로 확인 된 후 서비스가 이동 된 경우와 같이 여러 가지 이유로 인해 연결 시도가 실패 할 수 있습니다. 이 경우 이전의 해결 및 연결 단계를 다시 시도해야하며 연결이 성공할 때까지이주기가 반복됩니다. 서비스가 마지막 시간 이후 이동 한 경우

마지막 부분은 귀하의 질문에 매우 관련이있다, 실제로 해결 한 후 연결을 시도합니다. 즉, 이는 패브릭 전송을 사용하여 원격 서비스에 실제로이 시나리오를 처리하는 메커니즘이 내장되어 있음을 의미합니다.

IServiceProxyFactory (Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxyFactory)의 기본 구현을 호출하면 IServiceRemotingClient을 사용하여 통신하는 ServiceProxy를 얻을 수 있습니다. 해당 IServiceRemotingClient의 재시도 부분에 연결된 IExceptionHandler은 알려진 패브릭 오류와 관련된 일시적 오류 및 비 일시적인 오류를 다시 시도합니다. 그 중 하나는 서비스의 주소가 어떻게 든 바뀌 었다는 것입니다.

사용하기 쉬운 정적 ServiceProxy 클래스 (ServiceProxy.Create<...>에서 사용)가 있으며, 실제로는 후드 아래 Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxyFactory 만 사용합니다. 그의 답변에서 @LoekD가 지적한 것처럼, 생성자에 IServiceProxyFactory의 인스턴스를 삽입하는 방식은 테스트에 도움이됩니다. 라이브 코드에서는 Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxyFactory의 인스턴스를 삽입하고 테스트 할 때 자신 만의 모의 객체를 제공합니다. 코드에서 정적 인 ServiceProxy과 비슷한 코드를 사용합니다. _serviceProxyFactory.Create<IMyService>(...).

주, 다른 한편으로는 구현하는 경우 자신의 IServiceRemotingClient 다음과 같은 FabricNotReadableExceptionFabricTransientException 등을 재 시도 다양한 패브릭 예외를 (고려해야합니다. FabricClients에서 일반적 예외에 대한 자세한 내용은 https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-errors-and-exceptions을 확인합니다.

관련 문제