我是Play的初学者,所以请耐心等待。我试图让我的Play控制器与我的后端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://[email protected]:2551/user/connection");
}
我的Akka集群正在运行,我可以看到这三个节点不断互相闲聊。
问题是我在调用createSession时遇到以下错误:play.api.http.HttpErrorHandlerExceptions $$ anon $ 1:执行异常[[CompletionException:akka.pattern.AskTimeoutException:在[ActorSelection]上定时超时[Anchor(akka://) application(dead / deadLetters),Path(/ user / connection)]]在[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()
);
}
我做错了什么?
好吧,我现在通过了这个障碍。而且我想我不妨与其他人分享,希望答案可以帮助别人。问题实际上是我正在注入Play的ActorSystem,而实际上我需要配置自己的。所以这就是我所做的1. Inside Play的conf / application.config我添加了
play.akka.actor-system = "sharding"
这是我在端口2551,2552和0上运行的Akka Cluster的名称。我还在同一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://[email protected]: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中的连接分片发送了一条消息。但是我发现了,如果我错了,请纠正我,如果你在一个分片区域内创建了你的演员,你不应该使用他们的/ user / {actorType}(例如/ user / connection)从外部调用它们,而是你应该使用/ system / {ClusterName} / {ActorType},(在我的例子中是/ system / sharding / connection)所以我改变了我的代码
public CompletionStage<Result> createSession(int connectionId){
shardRegion = system.actorSelection("akka.tcp://[email protected]: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://[email protected]:2551/**system/sharding**/connection");
return FutureConverters.toJava(ask(shardRegion, new CreateSessionMessage(connectionId), 2000))
.thenApply(response -> ok((String) response));
}
当玩家控制器在otder中调用Akka分片区域来创建演员时,这是正确的理解吗?