扩展Akka.Net

时间:2018-11-21 16:04:40

标签: c# akka.net

我们将Akka.net框架用于能源领域的高度扩展应用。

我们将Akka.net用于各种任务,主要采用以下形式:

var system=ActorSystem.Create("actorSystem");
var props=Props.Create<UpdateActor>();
               .WithRouter(new SmallesMailboxPool(100));
var actorRef=system.ActorOf(props,"UpdateActor");
foreach(var timerow in timeRowList)
   actorRef.Tell(timerow)

不幸的是,在许多情况下,Akka.net框架的伸缩性非常差。 CPU负载仅为12%。 显然只使用了一个线程或几个线程。

如何将Akka.Net配置为使用多个线程来处理演员?

2 个答案:

答案 0 :(得分:1)

这是一个有根据的猜测,但是请记住,如果使用的是SmallestMailboxPool,则它在非阻塞I / O上和在隐藏中都非常糟糕。

第一件事通常是检查是否存在阻塞操作(例如同步I / O,调用AsyncMethod().ResultThread.Sleep),这些操作将阻塞当前线程,从而有效地防止其被其他线程使用。其他演员。

另一个问题是最小的邮箱路由器所特有的,它与隐藏和持久参与者有关。

隐藏

隐藏是使用多步操作的流行方法之一。这种模式可以表示为波纹管。

  public class MyActor : ActorBase, IWithUnboundedStash
  {
     public IStash Stash { get; set; }

     public Receive Active(State workUnit) => message =>
     {
        switch(message)
        {
           case DoWork: 
              // stash all messages not related to current work
              Stash.Stash(message); 
              return true;
           case WorkDone done:
              // when current unit of work is done, unstash pending messages
              Stash.UnstashAll();
              Become(Idle);
              return true;
        }
     };

     public bool Idle(object message)
     {
        switch(message)
        {
           case DoWork work: 
              StartWork(work.State);
              Become(Active(work.State)); //continue work in new behavior
              return true;
           default: 
              return false;
        }
     } 

     public bool Receive(object message) => Idle(message);
  }

这种情况很常见,即持久性参与者在其恢复过程中使用它。问题在于,它正在清理邮箱,这使SmallestMailbox路由器误认为该参与者的邮箱为空,而实际上它只是存储所有传入消息。

这也是为什么不应该使用SmallestMailbox路由器路由永久角色的原因! Tbh。我想不出将永久角色放置在任何类型的路由器后面的任何方案都是有效的选择。

答案 1 :(得分:0)

我认为您需要做的是创建一个演员协调器类,并在其中创建一个演员列表/字典。然后(据我了解),在您告诉协调员新更新后,它们应该并行工作。

location