在服务结构中的状态服务中注入无状态服务

时间:2017-01-09 07:14:30

标签: azure-service-fabric service-fabric-stateful

我有状态服务,处理可靠队列中的数据(在while循环内)。数据处理实际上称为无状态服务。

由于无状态服务可以从一个节点移动到另一个节点,因此在有状态服务的构造函数中注入此依赖关系(无状态服务)是否安全?只是想确保在构造函数中初始化/注入的依赖项不能修复一个节点。

2 个答案:

答案 0 :(得分: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);
        }
    }

答案 1 :(得分:0)

TL; DR; 是的,您可以,服务远程客户端在大多数情况下为您处理该方案。

<强>解释: 当您创建使用服务远程处理与服务通信的代理时,您将获得能够重试与实际服务的通信的客户端。在文档(https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-connect-and-communicate-with-services)中有关于此的一些描述,尤其是描述服务发现和解决方案的部分:

  

解析和连接服务涉及在循环中运行以下步骤:

     
      
  • 解决:获取服务已从命名服务发布的端点。
  •   
  • 连接:通过在该端点上使用的任何协议连接到该服务。
  •   
  • 重试:连接尝试可能由于多种原因而失败,例如,自上次解析端点地址以来服务已移动。在这种情况下,需要重试上述解决和连接步骤,并重复此循环,直到连接成功。
  •   

最后一部分与您的问题非常相关,如果服务自上次移动后,它实际上会重试Resolve,然后重新连接。因此,这意味着如果您使用结构传输到远程服务,实际上有一种内置机制来处理这种情况。

当您调用IServiceProxyFactoryMicrosoft.ServiceFabric.Services.Remoting.Client.ServiceProxyFactory)的默认实现时,您会获得一个使用IServiceRemotingClient进行通信的ServiceProxy。 在IServiceRemotingClient的重试部分中,与IExceptionHandler关联的ServiceProxy.Create<...>如果与已知结构错误相关,则会重试瞬态和非瞬态错误。其中一个原因是服务的地址以某种方式改变了。

有一个易于使用的静态ServiceProxy类(通过Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxyFactory使用),这个类实际上只使用了IServiceProxyFactory。正如@LoekD在他的回答中所指出的那样,在构造函数中注入Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxyFactory实例的方法可以帮助您进行测试。在实时代码中,您注入ServiceProxy的实例,并在测试中提供您自己的模拟。在您的代码中,您使用它类似于静态_serviceProxyFactory.Create<IMyService>(...),例如IServiceRemotingClient

注意,如果您另一方面实现自己的FabricNotReadableException,则需要考虑重试各种结构异常(例如FabricTransientException和{{1}}。请检查{{3有关FabricClients中常见异常的更多详细信息。