Hello Akka

从其它的网上教程中,我们很容易找到各种 Akka 相关的教程。但是可能是因为自己太笨,都没看明白。 于是自己写下这样一篇笔记,作以记录。 关于 Actor 模型的概念,就不在这里赘述了。 在编写 Akka 代码之前,先要加入 Mave 依赖:

<dependency>
    <groupId>com.typesafe.akka</groupId>
    <artifactId>akka-actor_2.11</artifactId>
    <version>2.4.4</version>
</dependency>

以下是第一个 Akka 代码,非常简单:

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.actor.UntypedActor;

public class HelloAkka {
    public static void main(String[] argArr) {
        ActorSystem systemObj = ActorSystem.create("helloAkka");
        ActorRef actorRef = systemObj.actorOf(Props.create(Actor_SayHello.class));
        actorRef.tell("hello Akka!", ActorRef.noSender());
    }
}

class Actor_SayHello extends UntypedActor {
    @Override
    public void onReceive(Object objMsg) throws Exception {
        System.out.println("receive : " + objMsg);
    }
}

运行 HelloAkka 后,屏幕上会输出:"receive : hello Akka!”。 这个 Actor_SayHello 既是消息的发布者又是消息的接收者,有点自言自语的意思。 这是一个 Akka 的 Hello World 程序,虽然简单,但是基本上没有实用价值。

接下来,修改一下上面的程序,将 Actor_SayHello 改名为 Actor_Master。 然后我们再建立一个 Actor_Slave 类。 Actor_Master 好比是主人,Actor_Slave 好比是仆人, 主人告诉仆人:干活去!

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.actor.UntypedActor;

public class HelloAkka {
    public static void main(String[] argArr) {
        ActorSystem systemObj = ActorSystem.create("helloAkka");
        ActorRef actorRef = systemObj.actorOf(Props.create(Actor_Master.class));
        actorRef.tell("hello Akka!", ActorRef.noSender());
    }
}

class Actor_Master extends UntypedActor {
    @Override
    public void onReceive(Object objMsg) throws Exception {
        // 注意 : 在这里创建另外一个 Actor,也就是 Actor_Slave
        ActorRef slave = this.getContext().actorOf(Props.create(Actor_Slave.class));
        slave.tell("go to work!", this.getSelf());
    }
}

class Actor_Slave extends UntypedActor {
    @Override
    public void onReceive(Object objMsg) throws Exception {
        if (objMsg.equals("go to work!")) {
            // 只有收到 go to work! 这条消息时,
            // 才输出 yes sir!
            System.out.println("yes sir!");
        }
    }
}

这样,我们就把消息的发布者和消息的接收者分开了。

下面,玩个更刺激的! 让主人与仆人运行在两个不同的机器上,怎么样? 主人运行在 192.168.1.11 这台机器上,端口号是:4711,而 仆人运行在 192.168.1.12 这台机器上,端口号是:4712。

为此,我们需要再多加一个 Maven 依赖:

<dependency>
    <groupId>com.typesafe.akka</groupId>
    <artifactId>akka-remote_2.11</artifactId>
    <version>2.4.4</version>
</dependency>

首先是主人代码 App_Master:

import akka.actor.ActorRef;
import akka.actor.ActorSelection;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.actor.UntypedActor;
import com.typesafe.config.ConfigFactory;

import java.util.HashMap;
import java.util.Map;

public class App_Master {
    public static void main(String[] argArr) {
        Map<String, String> propMap = new HashMap<>();
        // 这个 RemoteActorRefProvider 是要加上的

        propMap.put("akka.actor.provider", "akka.remote.RemoteActorRefProvider");
        propMap.put("akka.remote.netty.tcp.hostname", "192.168.1.11");
        propMap.put("akka.remote.netty.tcp.port", "4711");

        ActorSystem systemObj = ActorSystem.create(
            "helloAkka",
            ConfigFactory.parseMap(propMap)
        );

        ActorRef actorRef = systemObj.actorOf(Props.create(Actor_Master.class), "master");
        actorRef.tell("hello Akka!", ActorRef.noSender());
    }
}

class Actor_Master extends UntypedActor {
    @Override
    public void onReceive(Object objMsg) throws Exception {
        // 注意 : 这里是通过 IP 地址拿到 Actor_Slave 的
        ActorSelection slave = this.getContext().actorSelection("akka.tcp://helloAkka@192.168.1.12:4712/user/slave");
        slave.tell("go to work!", this.getSelf());
    }
}

之后是仆人代码 App_Slave:

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.actor.UntypedActor;
import com.typesafe.config.ConfigFactory;

import java.util.HashMap;
import java.util.Map;

public class App_Slave {
    public static void main(String[] argArr) {
        Map<String, String> propMap = new HashMap<>();
        propMap.put("akka.actor.provider", "akka.remote.RemoteActorRefProvider");
        propMap.put("akka.remote.netty.tcp.hostname", "192.168.1.12");
        propMap.put("akka.remote.netty.tcp.port", "4712");

        ActorSystem systemObj = ActorSystem.create(
            "helloAkka",
            ConfigFactory.parseMap(propMap)
        );

        ActorRef actorRef = systemObj.actorOf(Props.create(Actor_Slave.class), "slave");
        actorRef.tell("hello Akka!", ActorRef.noSender());
    }
}

class Actor_Slave extends UntypedActor {
    @Override
    public void onReceive(Object objMsg) throws Exception {
        if (objMsg.equals("go to work!")) {
            System.out.println("yes sir!");
        }
    }
}

注意:先启动仆人 App_Slave,然后再启动主人 App_Master。在仆人那一边,屏幕上会显示:yes sir! 真刺激!

转载于:https://my.oschina.net/hjj2017/blog/674075

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值