Azure Service Fabric:直接在 ASP.NET 核心有状态服务中使用可靠集合

Azure Service Fabric: Using Reliable collections in ASP.NET Core Stateful Service directly

我用两个服务构建了一个 Service Fabric 应用程序:

  1. 状态数据服务,将数据存储在可靠的字典中,并向字典中的 add/remove/get 数据项公开方法。
  2. 一种无状态 Web API 服务,它充当与外界的 HTTP 接口,并使用远程处理与数据服务进行通信以获取数据并显示给用户。

在 Service Fabric 中提供了创建有状态 Web API 服务的规定。我试图摆脱数据服务并仅在 Web API 服务中管理可靠的字典。但是,我无法在我的控制器中访问 StateManager。我无法在网上找到任何执行此操作的示例。

我对有状态 ASP.NET 核心 API 服务的理解是否正确?也就是我可以直接在里面使用可靠的集合?

是 - 您可以在 asp.net 服务中使用可靠的集合。此示例等同于您正在构建的内容:https://github.com/Azure-Samples/service-fabric-dotnet-quickstart 它包含一个 asp.net 核心有状态服务。

主要内容:

  1. 您的服务必须来自 Microsoft.ServiceFabric.Services.Runtime.StatefulService
  2. 在 serviceListener 中,您设置了一个 ServiceReplicaListener(不是 ServiceInstanceListener)
  3. 在 WebHostbuilder 中添加一个单例 IRealibleStatemanager:.AddSingleton(this.StateManager))

现在您的控制器将可以访问单例状态管理器:

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

如果需要扩展,还应该考虑分区。 在那种情况下,也许单独的服务更好。

(不是真正的答案,但我不能发表评论,因为我还不到 50 分:))

如果您希望服务在所有节点上可用,请允许在辅助副本上侦听。

protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners(){
    return new ServiceReplicaListener[]{
        new ServiceReplicaListener(serviceContext =>
            new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) => {
                EventTracer.Current.LogSystemMessage(serviceContext, $"Starting http kestrel listner on {url}");
                return new WebHostBuilder()
                    .UseKestrel()
                    .ConfigureServices(
                         services => services
                         .AddSingleton<StatefulServiceContext>(serviceContext)
                         .AddSingleton<IReliableStateManager>(this.StateManager))
                     .UseContentRoot(Directory.GetCurrentDirectory())
                     .UseStartup<Startup>()
                     .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                     .UseUrls(url)
                     .Build();
            }),"WebService",listenOnSecondary:true)

    };
}