【问题标题】:Service Fabric spawn actor on startupService Fabric 在启动时生成 Actor
【发布时间】:2016-08-12 07:14:01
【问题描述】:

有没有办法要求系统在启动时产生某些演员。

目前我在演员注册后在Program.cs中激活了我需要的演员集。

这工作正常,但我偶尔会收到ReminderLoadInProgressException,因为被激活的演员需要注册提醒,但在尝试这样做时并非所有提醒都已加载。

是否有标准方法来播种集群?

【问题讨论】:

  • 你不能用提醒来做这件事吗?我最近没看演员。

标签: c# azure-service-fabric service-fabric-actor


【解决方案1】:

不,你需要一些东西来激活你的演员。

Program.cs 不是执行此操作的最佳位置,因为您可能已经注意到,它的执行与您的服务的生命周期并不相符。

如果您需要在您的演员服务启动时激活一些演员,那么执行此操作的好地方是您的演员服务的 RunAsync 方法。您可以通过编写派生自它的服务来自定义您的参与者服务,就像您编写有状态服务时所做的一样:

编辑:确保首先调用并等待 base.RunAsync()!

class MyActorService : ActorService
{
    public MyActorService(StatefulServiceContext context, ActorTypeInformation typeInfo, Func<ActorBase> newActor)
        : base(context, typeInfo, newActor)
    { }

    protected async override Task RunAsync(CancellationToken cancellationToken)
    {
        await base.RunAsync(cancellationToken);

        var proxy = ActorProxy.Create<IMyActor>(new ActorId(0));
        await proxy.StartDoingStuff();
    }
}

然后注册您的演员服务,以便运行时知道使用它来托管您的演员实例:

static class Program
{
    private static void Main()
    {
        ActorRuntime.RegisterActorAsync<MyActor>(
            (context, actorType) => new MyActorService(context, actorType, () => new MyActor()))
            .GetAwaiter().GetResult();

        Thread.Sleep(Timeout.Infinite);
    }
}

只要确保actor方法是幂等的,因为每次启动actor服务的主副本时都会执行(在故障转移、资源平衡、应用程序升级等之后),但好的是它不会在你的actor服务准备好之前执行,它总是会在服务启动时执行。

有关如何使用演员服务的更多信息,请参见此处:https://azure.microsoft.com/en-us/documentation/articles/service-fabric-reliable-actors-platform/

【讨论】:

  • 我们正在使用这个解决方案来启动(目前)大约 1500 个 Actor 实例。由于我们仍处于测试阶段,演员们没有做任何事情。然而,在 5 节点集群(A1 机器)上,所有节点都在消耗大量 CPU(大部分时间处于 100% 使用率)。你觉得这正常吗?我们计划使用这种技术来生成 20K 个实例来实际做某事(意味着做真正的工作,而不是像现在这样等待)。您能就“好方法”提出建议吗?
  • 在自定义 ActorService 子类中调用 base.RunAsync 是不够的 - 您仍会偶尔收到 ReminderLoadInProgressException,如本示例应用程序 - github.com/PaloMraz/SpawnActorsApp 所示。在本地 5Node 开发集群上从 VS 运行几次,您肯定会在“诊断事件”窗口中看到“********* RegisterReminderAsync failed”消息……
  • 在上面的示例中,我实现了一个解决方法,使用参与者计时器重试提醒注册。如果您想查看上面讨论的错误行为,请查看之前的提交github.com/PaloMraz/SpawnActorsApp/commit/…
【解决方案2】:

无法评论,所以我把评论放在这里:

为了完整起见:如果您的 ActorService 子类没有默认名称(来自 ServiceManifest.xml - 例如您动态生成服务实例),您将不得不像这样使用双参数 ActorProxy.Create 重载:

var actor = ActorProxy.Create<IMyActor>(new ActorId(0), this.Context.ServiceName);

否则你会得到“服务不存在”的异常:

System.Fabric.FabricServiceNotFoundException: Service does not exist. 
---> System.Runtime.InteropServices.COMException: Exception from HRESULT: 0x80071BCD at
System.Fabric.Interop.NativeClient.IFabricServiceManagementClient4
.EndResolveServicePartition(IFabricAsyncOperationContext context)
...

【讨论】:

  • 这对于评论来说也太长了 :-) 感谢您的贡献!
猜你喜欢
  • 2015-09-06
  • 2016-03-11
  • 2018-01-11
  • 2017-07-19
  • 1970-01-01
  • 2018-01-03
  • 1970-01-01
  • 2020-04-03
  • 2019-11-07
相关资源
最近更新 更多