首页 > 解决方案 > 本地缓存的 stateManager ... Service Fabric 中的任何风险?

问题描述

在 Service Fabric 中,看似常见的做法可能是错误的做法。我怀疑以下将 stateManager 保存为本地缓存的代码在“SomeService”有状态服务中的“CreateServiceReplicaListeners()”方法的返回语句中实例化“Startup”类时可能会导致潜在问题。

可能发生的情况是状态管理器以某种方式重新实例化。我需要更多解释以下做法是否正确。如果不是,那么最好的做法是什么?

internal class SomeService : StatefulService
{
    protected  override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
    {
        return new[]{
            new ServiceReplicaListener(
                        initParams =>
                            new OwinCommunicationListener("SomeService", new Startup(this.StateManager), initParams))
                };
        }
    }
}

public class Startup : IOwinAppBuilder
{
    private readonly IReliableStateManager stateManager;

    public Startup(IReliableStateManager stateManager)
    {
        this.stateManager = stateManager;
    }

    public void Configuration(IAppBuilder appBuilder)
    {
        // other initialization codes..
        ...
        ...

        UnityConfig.RegisterComponents(config, this.stateManager);

        appBuilder.UseWebApi(config);
    }
}

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

解决方案


每当有状态服务更改角色时,它都会触发IStatefulServiceReplica.ChangeRoleAsync(ReplicaRole newRole, CancellationToken cancellationToken).

ChangeRoleAsync(..)确保新角色使用正确的通信,执行以下操作:

  • 调用CloseCommunicationListenersAsync(CancellationToken cancellationToken)以关闭任何打开的侦听器
  • 征集主要ActiveSecondary角色OpenCommunicationListenersAsync(newRole, cancellationToken)_
  • 该方法OpenCommunicationListenersAsync()将调用CreateServiceReplicaListeners()以获取侦听器并CreateCommunicationListener(serviceContext)为每个返回的侦听器调用以打开相关端点。

角色变更在升级和负载均衡过程中很常见,所以这是一个很常见的事件。

总之,

每次角色变更发生时,CreateServiceReplicaListeners()都会被调用,ChangeRole不会关闭服务,因此它可能会产生副作用,例如如果您在 DI 容器中注册依赖项,您可能会面临重复注册。


推荐阅读