Akka和Spring集成

y

我正在尝试让akka使用spring应用程序。这是一款非常适合akka模型的搜索应用。关于这种集成的大多数在线和关于类型安全的示例都谈论使用akka扩展来注入spring应用程序上下文。然而,它们都使用ActorSystem.actorOf()方法来创建演员,这被认为是昂贵的操作。

ActorSystem system = ctx.getBean(ActorSystem.class);
system.actorOf(.....)

参见-https://github.com/typesafehub/activator-akka-java-spring/blob/master/src/main/java/sample/Main.java

我想使用参与者来处理每个通过身份验证的Web请求。使用以上代码,我最终将为每个不理想的请求创建root actor。

任何指针将不胜感激。

尼克比特

以下内容并未回答原始问题,该问题是关于减少对Web应用程序的请求时通常需要创建的新参与者的数量。

要使用Akka路由器做到这一点,可以像下面的代码行一样简单:

getContext().actorOf(SpringExtProvider.get(getContext().system()).props("AnotherActor.").withRouter(new RoundRobinPool(100)), "another");

Akka文档提供了有关配置的更多详细信息,尽管值得一看http://doc.akka.io/docs/akka/snapshot/java/routing.html最好通过Akka配置文件定义其行为,而不是硬编码到应用程序中。您可以这样称呼它:

getContext().actorOf(SpringExtProvider.get(getContext().system()).props("AnotherActor.").withRouter(new FromConfig()), "another");

..并在application.conf文件中定义路由器的类型和行为。

如果您还没有考虑过,那么还值得一试的是如何使您的Web请求异步化。一种方法是使用Spring的DeferredResult并将其实例传递给您的actor,并在搜索请求完成时设置结果。

-更新20 / 11--

我认为为什么actor选择对您不起作用是因为您试图使用bean名称,而不是actor名称作为actor选择的范围。创建路由器时,您无需指定角色名称,因此Akka会在内部为其指定名称,例如“ $ a”之类的名称。

为了说明这一点,如果您使用以下方法创建演员:

actorSystem.actorOf(this.get(actorSystem).props(applicationContext, "bean_name"), "actorName");

然后,您应该能够执行演员选择:

actorSystem.actorSelection("actorName");

或者,一次创建上述路由器actor,然后在对Spring MVC Web服务发出的每个请求中重新使用它,则可以在Spring @Configuration类中创建它,并将ActorRef作为bean公开,以便您可以将其插入您的Spring @Controller类。以下是我创建frmo内存的快速示例,因此请确保已对其进行测试/编译等。

@Configuration
public class Config {

   @Autowired
   private ActorSystem actorSystem;

   @Bean(name = "routerActorRef")
   public ActorRef routerActorRef() { 
      getContext().actorOf(SpringExtProvider.get(actorSystem).props("AnotherActor").withRouter(new RoundRobinPool(100)), "another");
   }

}

然后,您可以通过编写如下代码将其注入另一个Spring bean:

@Autowired
@Qualifier("routerActorRef")
private ActorRef routerActorRef;

应该注意的是,这仅对于顶级参与者才是真正可行的,对于较低级别的参与者可能是可行的,但是要有效地进行管理将变得非常棘手。

-原始答案-

链接到Main方法中的示例显示了如何创建初始的顶级actor,该顶级actor将由基于系统的“用户” actor进行监督。这是一个非常简单的示例,演示了如何创建一个名为CountingActor的Spring托管角色,并在其中注入了一个名为CountingService的Spring托管bean。

为了进一步说明该示例,您可以定义另一个与CountingActor相似的actor,例如

@Named("AnotherActor")
@Scope("prototype")
class AnotherActor extends UntypedActor {

  // the service that will be automatically injected
  final AnotherService anotherService;

  @Inject
  public AnotherActor(@Named("AnotherService") AnotherService anotherService) {
    this.anotherService = anotherService;
  }    

  @Override
  public void onReceive(Object message) throws Exception {
    if (message == "doSomething") {
      anotherService.doSomething();
    } else {
      unhandled(message);
    }
  }
}

我假设还有一个名为AnotherService的Spring服务bean,它具有doSomething()方法,该方法将在创建AnotherActor时注入。

然后,在CountingActor中,您可以像这样创建AnotherActor:

@Named("CountingActor")
@Scope("prototype")
class CountingActor extends UntypedActor {

  public static class Count {}
  public static class Get {}

  // the service that will be automatically injected
  final CountingService countingService;

  @Inject
  public CountingActor(@Named("CountingService") CountingService countingService) {
    this.countingService = countingService;
  }

  private int count = 0;

  @Override
  public void onReceive(Object message) throws Exception {
    if (message instanceof Count) {
      count = countingService.increment(count);
      // Create AnotherActor here as a child of CountingActor by using the CountingActor's context
      ActorRef anotherActor = getContext().actorOf(SpringExtProvider.get(system).props("AnotherActor"), "another");
      anotherActor.tell("doSomething", getSelf());
    } else if (message instanceof Get) {
      getSender().tell(count, getSelf());
    } else {
      unhandled(message);
    }
  }
}

此处与创建actor的主要区别主要是使用getContext()。actorOf(...)而不是system.actorOf(...)。使用getContext()会导致将新的Actor创建为CounterActor的子级,而不是顶级“用户” actor。

在Akka官方文档中对此行为有很好的描述:http : //doc.akka.io/docs/akka/snapshot/java/untyped-actors.html#creating-actors-with-props

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章