尝试向Akka群集发送请求时,播放控制器会引发AskTimeoutException

时间:2019-04-25 22:07:42

标签: playframework akka-cluster

我是玩游戏的初学者,所以请多多包涵。 我正在尝试让我的播放控制器与后端Akka群集进行通信。 html get请求被路由到我的Controller中的以下方法:

    public CompletionStage<Result> createSession(int connectionId){
        return FutureConverters.toJava(ask(shardRegion, new CreateSessionMessage(connectionId), 2000))
                .thenApply(response -> ok((String) response));
    }

其中

@Inject
    public ConnectionController(ActorSystem system) {
//other things
shardRegion = system.actorSelection("akka.tcp://sharding@127.0.0.1:2551/user/connection"); 
}

我的Akka群集正在运行,我可以看到三个节点一直在闲聊。

问题是调用createSession时出现以下错误: play.api.http.HttpErrorHandlerExceptions $$ anon $ 1:执行例外[[CompletionException:akka.pattern.AskTimeoutException:在[ActorSelection [Anchor(akka:// application / deadLetters),Path(/ user / [连接)]] [2000 ms]之后。类型为[com.vegaspin.actors.connection.ConnectionActorMessage $ CreateSessionMessage]的消息。 AskTimeoutException的典型原因是收件人演员没有发送回复。]]

我的Akka群集称为“分片”。我不确定为什么在错误消息中显示akka:// application / deadLetters

这是用于创建“连接”集群分片的代码

    private static ActorRef setupConnectionClusterSharding(ActorSystem actorSystem) {
        ClusterShardingSettings settings = ClusterShardingSettings.create(actorSystem);
        return ClusterSharding.get(actorSystem).start(
                "connection",
                SpringExtProvider.get(actorSystem).props("ConnectionActor"),
                settings,
                ConnectionActorMessage.messageExtractor()
        );
    }

我在做什么错了?

1 个答案:

答案 0 :(得分:0)

好的,我现在克服了这个障碍。我想我也希望与他人分享,希望答案能对某人有所帮助。 问题实际上是我在注入Play的ActorSystem时实际上需要配置自己的。所以这就是我所做的 1.在Play的conf / application.config中,我添加了

play.akka.actor-system = "sharding" 

这是我在端口2551、2552和0上运行的Akka群集的名称。 我还在同一application.config文件的Akka块中添加了以下信息。

  actor {
    provider = "akka.remote.RemoteActorRefProvider" # offer the provider
  }

  remote {
    enabled-transports = ["akka.remote.netty.tcp"] 
    netty.tcp {
      hostname = "127.0.0.1" # your host
      port = 2553 # port
    }
  }

如您所见,我必须更改端口以避免端口绑定异常。我在其他主题的有用评论之一中读到了这一点。

这解决了问题,我继续处理一个新问题,这是Akka群集中抛出的异常

[INFO] [04/27/2019 13:02:05.329] [sharding-akka.actor.default-dispatcher-23] [akka://sharding/user/connection] Message [com.actors.connection.ConnectionActorMessage$CreateSessionMessage] from Actor[akka.tcp://sharding@127.0.0.1:2553/temp/$a] to Actor[akka://sharding/user/connection] was not delivered. [3] dead letters encountered. If this is not an expected behavior, then [Actor[akka://sharding/user/connection]] may have terminated unexpectedly, This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

所以至少现在我可以看到Play控制器确实向后端AkkaCluster中的连接分片发送了一条消息。但是我发现了,如果我错了,请更正我,如果您在片段区域内创建了actor,则不应使用它们的/ user / {actorType}(例如/ user / connection)从外部调用它们,而是您应该使用/ system / {ClusterName} / {ActorType},(例如,在我的情况下为/ system / sharding / connection) 所以我从更改了代码

public CompletionStage<Result> createSession(int connectionId){
        shardRegion = system.actorSelection("akka.tcp://sharding@127.0.0.1:2551/**user**/connection");
        return FutureConverters.toJava(ask(shardRegion, new CreateSessionMessage(connectionId), 2000))
                .thenApply(response -> ok((String) response));
    }

public CompletionStage<Result> createSession(int connectionId){
        shardRegion = system.actorSelection("akka.tcp://sharding@127.0.0.1:2551/**system/sharding**/connection");
        return FutureConverters.toJava(ask(shardRegion, new CreateSessionMessage(connectionId), 2000))
                .thenApply(response -> ok((String) response));
    }

关于让Play控制器在另一端调用Akka碎片区域来创建演员的说法是否正确?