Akka远程路由使用Java



我正在尝试实现一个基本的广播路由器,其中路由在远程计算机上。

代码如下:

localapp.conf

akka {
    log-dead-letters = 10
    log-dead-letters-during-shutdown = off
    actor {
        provider = "akka.remote.RemoteActorRefProvider"
        serialize-messages = on
        serializers {
            java = "akka.serialization.JavaSerializer"
        }
        serialization-bindings {
            "java.lang.String" = java
            "test.akkaLocal.LocalWrapper" = java
        }
        deployment {
            /LocalMaster/broadcastRouter {
                router = "broadcast"
                nr-of-instances = 1
                target {
                    nodes = ["akka.tcp://RemoteApp@127.0.0.1:10175"]
                }
            }
        }
    }
    remote {
        enabled-transports = ["akka.remote.netty.tcp"]
        netty {
            tcp {
                hostname = "127.0.0.1"
                port = 10174
            }
        }
    }
}

localapp.java

public class LocalApp
{
    public static void main(String[] args)
    {
        LocalApp app = new LocalApp();
        app.executeLocal();
    }
    private void executeLocal() {
        ActorSystem system = ActorSystem.create("LocalApp", ConfigFactory.load("localApp"));
        final ActorRef master = system.actorOf(Props.create(LocalMaster.class), "LocalMaster");
        master.tell(new LocalWrapper.Execute(), ActorRef.noSender());
    }
    public static class LocalMaster extends UntypedActor {
        @Override
        public void onReceive(Object message) throws Exception {
            if (message instanceof LocalWrapper.Execute) {
                ActorSelection remoteActor =
                        getContext().actorSelection("akka.tcp://RemoteApp@127.0.0.1:10175/user/RemoteMaster");
                ActorRef remoteRouter = getContext().actorOf(
                        Props.create(RemoteActor.class).withRouter(new FromConfig()), "broadcastRouter");
                String msg = "Hello";
                // remoteActor.tell(msg, getSelf());
                remoteRouter.tell(msg, getSelf());
            } else if (message instanceof String) {
                String response = (String) message;
                System.out.println(response);
            }
        }
    }
    public static class RemoteActor extends UntypedActor {
        @Override
        public void onReceive(Object message) throws Exception {
            if (message instanceof String) {
                String msg = (String) message;
                System.out.println(msg);
                String resp = "World";
                getSender().tell(resp, getSelf());
            }
        }
    }
}

在remoteapp.conf中,端口以10175

给出

remoteapp.java

public class RemoteApp
{
    public static void main(String[] args)
    {
        RemoteApp app = new RemoteApp();
        app.executeRemote();
    }
    private void executeRemote() {
        ActorSystem system = ActorSystem.create("RemoteApp", ConfigFactory.load("remoteApp"));
        system.actorOf(Props.create(RemoteMaster.class), "RemoteMaster");
    }
    public static class RemoteMaster extends UntypedActor {
        @Override
        public void onReceive(Object message) throws Exception {
            if (message instanceof String) {
                String msg = (String) message;
                System.out.println(msg);
                String response = "World";
                getSender().tell(response, getSelf());
            }
        }
    }
}

现在我无法理解远程路由的概念。它是在远程计算机上部署本地演员,然后将消息发送给他们,还是在远程计算机上连接到远程演员,然后将消息发送给他们?

使用我的代码,我能够将简单消息发送到远程计算机(使用Actor选择)remoteactor.tell(msg,get self())(注释代码)在localApp发送和接收消息,并且没有任何错误。

但是,当我使用本地演员创建路由器时,我会收到死字母错误。

[INFO] [02/04/2014 16:34:58.408] [RemoteApp-akka.actor.default-dispatcher-4] [akka://RemoteApp/system/endpointManager/reliableEndpointWriter-akka.tcp%3A%2F%2FLocalApp%40127.0.0.1%3A10174-0/endpointWriter/endpointReader-akka.tcp%3A%2F%2FLocalApp%40127.0.0.1%3A10174-0] 
Message [akka.remote.transport.AssociationHandle$InboundPayload] from Actor[akka://RemoteApp/deadLetters] to Actor[akka://RemoteApp/system/endpointManager/reliableEndpointWriter-akka.tcp%3A%2F%2FLocalApp%40127.0.0.1%3A10174-0/endpointWriter/endpointReader-akka.tcp%3A%2F%2FLocalApp%40127.0.0.1%3A10174-0#-288427524] was not delivered.
[1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

有人可以告诉我我做错了什么吗?

------------------------------------------

我发现了这个问题。远程和本地课程在不同的项目中。在本地项目和远程项目之间的基本通信期间,字符串是转移对象的类型,即它是成功的原因。有没有办法在两个不同的项目之间传输自定义类的对象?我尝试实现序列化并将其添加到conf文件中,但没有区别

默认情况下,akka将使用Java序列化进行自定义消息类。如果在系统两侧(发送和接收侧)的类定义可用(即在类路径中),则您应该能够将其用于远程通信。我的建议是拥有一个jar文件,代表系统两侧的类路径中可用的消息类。

akka还将让您在不同的消息类类型中使用不同的序列化器,因此您不会陷入Java序列化,但是如果您觉得如此倾向,我建议您先以这种方式进行这种方式。

相关内容

  • 没有找到相关文章

最新更新