akka中的 actor和message

参考https://developer.lightbend.com/guides/akka-quickstart-java/define-actors.html

Messages可以是各种类型

Hello World Actors 用了三种类型

  • WhoToGreet:拜访接受者

  • Greet:执行拜访的说明

  • Greeting : 包含拜访的消息

定义好了Actors和Messages,需要注意下面几点:

  • 因为Messages是公共的API,所以一个最佳实践就是消息应该有一个好的名字,丰富的语义,特定作用域,甚至可以包括数据类型。这样易用,容易理解,容易调试。
  • Messages应该不变的,因为多个线程直接共享。
  • 还有一个最佳实践,把和actor相关联的消息,作为一个静态类放在Actor的类中。 这样就容易理解这个Actor期望和处理哪种类型的消息。
  • 还有一个常用的做法,在Actor中用静态的props的描述如何去构建这个Actor。

Greeter 和 Printer中使用最佳实践

The Greeter Actor

从Greeter.java 中截取的一部分

package com.lightbend.akka.sample;

import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.Props;
import com.lightbend.akka.sample.Printer.Greeting;

public class Greeter extends AbstractActor {
  static public Props props(String message, ActorRef printerActor) {
    return Props.create(Greeter.class, () -> new Greeter(message, printerActor));
  }

  static public class WhoToGreet {
    public final String who;

    public WhoToGreet(String who) {
        this.who = who;
    }
  }

  static public class Greet {
    public Greet() {
    }
  }

  private final String message;
  private final ActorRef printerActor;
  private String greeting = "";

  public Greeter(String message, ActorRef printerActor) {
    this.message = message;
    this.printerActor = printerActor;
  }

  @Override
  public Receive createReceive() {
    return receiveBuilder()
        .match(WhoToGreet.class, wtg -> {
          this.greeting = message + ", " + wtg.who;
        })
        .match(Greet.class, x -> {
          printerActor.tell(new Greeting(greeting), getSelf());
        })
        .build();
  }
}

让我们来分解下代码:

  • Greeter继承了AbstractActor重写了createReceive方法。
  • Greeter构造函数接受两个参数:String message 用于构建Greeting message, ActorRef printerActor是处理问候结果的Actor的引用。
  • receiveBuilder定义了对不同消息应该有不同的反应。一个Actor是可以有状态的。获取和改变内部状态是线程安全的,因为它被Actor model保护着。createReceive会按着Actor所期望的那样去处理消息。对于Greeter,它处理两种Message类型,WhoToGreet和Greet。前者会更新Actor的greeting状态,后者会触发发送消息到Printer Actor。
  • greeting变量包含着Actor的状态,默认被设置为''
  • 静态的props方法创建和返回一个Props实例。 Props实例是一个创建Actors参数集的配置类。可以认为他是一个不变的和可以被自由分享的菜单来创建Actor,可以包含部署的信息。这个例子,简单传递用于构建Actor所需要的参数。

Printer Actor

  • 它创建日志通过Logging.getLogger(getContext().getSystem(), this); 这样后就可以通过log.info() 来写日志。
  • 它处理一种message, Greeting. 然后输出日志。
package com.lightbend.akka.sample;

import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.event.Logging;
import akka.event.LoggingAdapter;

public class Printer extends AbstractActor {
  static public Props props() {
    return Props.create(Printer.class, () -> new Printer());
  }

  static public class Greeting {
    public final String message;

    public Greeting(String message) {
      this.message = message;
    }
  }

  private LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);

  public Printer() {
  }

  @Override
  public Receive createReceive() {
    return receiveBuilder()
        .match(Greeting.class, greeting -> {
            log.info(greeting.message);
        })
        .build();
  }
}

你可能感兴趣的:(akka中的 actor和message)