Play Controller выдает исключение AskTimeoutException при попытке отправить запрос в кластер Akka - PullRequest
0 голосов
/ 26 апреля 2019

Я новичок в игре, поэтому, пожалуйста, потерпите меня. Я пытаюсь заставить мой Play Controller связаться с моим внутренним кластером Akka. HTML-запрос get направляется в мой контроллер по следующему методу:

    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 мс]. Сообщение типа [com.vegaspin.actors.connection.ConnectionActorMessage $ CreateSessionMessage]. Типичная причина AskTimeoutException заключается в том, что получатель не отправил ответ.]]

Мой кластер Акка называется "шардинг". Я не уверен, почему в сообщении об ошибке написано 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 голосов
/ 27 апреля 2019

Хорошо, я преодолел это препятствие. И я подумал, что мог бы также поделиться этим с другими, надеюсь, что ответ кому-то поможет. Проблема заключалась в том, что я вводил ActorSystem от Play, хотя на самом деле мне нужно было настроить свою собственную. Итак, вот что я сделал 1. Внутри Play / conf / application.config я добавил

play.akka.actor-system = "sharding" 

- это имя моего кластера Akka, работающего через порт 2551, 2552 и 0. Я также добавил нижеприведенную информацию в блок Akka в тот же файл application.config.

  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. Однако я выяснил и исправлю меня, если я ошибаюсь, если ваши актеры созданы в области шарда, вы не должны вызывать их извне, используя их / 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 вызывал область осколков Акки в Отдере для создания актера?

...