Programing/Akka

Akka Tutorial

BUST 2017. 7. 1. 16:01

Akka Tutorial

Reference

Actor Model의 좋은 점

  • 이벤트 기반의 모델
    • Actor는 메시지를 통해 작업
    • Actor 사이간의 통신은 비동기, blocking 없이, 응답을 기다리지 않고 다른 작업을 할수가 있다.
  • 강한 격리 원칙
    • 일반적인 자바 객체와 달리 Actor는 자신이 가지고 있는 상태에 대한 API 존재하지 않는다. 대신에 메세지를 통해 공유가 가능하다.
    • 이는 다른 액터간의 상태(State)를 공유하는 것을 막는다.
    • 오로지 메세지를 보내는 것을 통해 다른 액테의 상태를 볼수가 있다.
  • 가벼움
    • 백만건이상을 처리할때도 액터는 각각의 인스턴트는 몇백 바이터 정도의 메모리를 사용한다.

Akka Quick Start Main Class

package com.lightbend.akka.sample;
 
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import com.lightbend.akka.sample.Greeter.*;
 
import java.io.IOException;
 
public class AkkaQuickstart {
  public static void main(String[] args) {
    // Actor System을 생성 
    final ActorSystem system = ActorSystem.create("helloakka");
    try {
      //#create-actors 
      final ActorRef printerActor =
        system.actorOf(Printer.props(), "printerActor");
      final ActorRef howdyGreeter =
        system.actorOf(Greeter.props("Howdy", printerActor), "howdyGreeter");
      final ActorRef helloGreeter =
        system.actorOf(Greeter.props("Hello", printerActor), "helloGreeter");
      final ActorRef goodDayGreeter =
        system.actorOf(Greeter.props("Good day", printerActor), "goodDayGreeter");
      //#create-actors 
 
      //#main-send-messages 
      howdyGreeter.tell(new WhoToGreet("Akka"), ActorRef.noSender());
      howdyGreeter.tell(new Greet(), ActorRef.noSender());
 
      howdyGreeter.tell(new WhoToGreet("Lightbend"), ActorRef.noSender());
      howdyGreeter.tell(new Greet(), ActorRef.noSender());
 
      helloGreeter.tell(new WhoToGreet("Java"), ActorRef.noSender());
      helloGreeter.tell(new Greet(), ActorRef.noSender());
 
      goodDayGreeter.tell(new WhoToGreet("Play"), ActorRef.noSender());
      goodDayGreeter.tell(new Greet(), ActorRef.noSender());
      //#main-send-messages 
 
      System.out.println(">>> Press ENTER to exit <<<");
      System.in.read();
    } catch (IOException ioe) {
    } finally {
      system.terminate();
    }
  }
}
 
  • ActorySystem는 Actor를 생성하기 위한 Factory이다.
  • actorOf 매서드는 Actor 생성하는 매서드이다. Props 객체를 통해 Actor를 생성한다.
  • ActorRef의 tell 매서드를 이용하여 메세지를 보낼수가 있다.

Greeter Class

package com.lightbend.akka.sample;
 
import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.Props;
import com.lightbend.akka.sample.Printer.Greeting;
 
//#greeter-messages 
public class Greeter extends AbstractActor {
//#greeter-messages 
  static public Props props(String message, ActorRef printerActor) {
    return Props.create(Greeter.class, () -> new Greeter(message, printerActor));
  }
 
  //#greeter-messages 
  static public class WhoToGreet {
    public final String who;
 
    public WhoToGreet(String who) {
        this.who = who;
    }
  }
 
  static public class Greet {
    public Greet() {
    }
  }
  //#greeter-messages 
 
  private final String message;
  private final ActorRef printerActor;
  private String greeting = "";
 
  public Greeter(String message, ActorRef printerActor) { // 외부에서 printActor를 주입 받는다. DI 
    this.message = message;
    this.printerActor = printerActor;
  }
 
  @Override
  public Receive createReceive() {
    return receiveBuilder()
        // 
        .match(WhoToGreet.class, wtg -> { // 내부의 State를 설정하는 Message 
          this.greeting = message + "" + wtg.who;
        })
        .match(Greet.class, x -> { // Action Message 
          //#greeter-send-message 
          printerActor.tell(new Greeting(greeting), getSelf());
          //#greeter-send-message 
        })
        .build();
  }
//#greeter-messages 
}
//#greeter-messages 
  • Greeter Class는 akka.actor.AbstractActor 클래스를 상속받아 createReceive 매서드를 구현한다.
  • Static prop method는 Props 객체를 생성해준다. Prop은 Actor의 설정 클래스이다.
  • receiveBuilder method는 메서지 처리 핸들러를 등록해준다.

Printer Class

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;
 
//#printer-messages 
public class Printer extends AbstractActor {
//#printer-messages 
  static public Props props() {
    return Props.create(Printer.class, () -> new Printer());
  }
 
  //#printer-messages 
  static public class Greeting {
    public final String message;
 
    public Greeting(String message) {
      this.message = message;
    }
  }
  //#printer-messages 
 
  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();
  }
//#printer-messages 
}
//#printer-messages 

Testing Actor

package com.lightbend.akka.sample;
 
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.testkit.javadsl.TestKit;
import com.lightbend.akka.sample.Greeter.*;
import com.lightbend.akka.sample.Printer.*;
 
import static org.junit.Assert.assertEquals;
 
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
 
public class AkkaQuickstartTest {
    static ActorSystem system;
 
    @BeforeClass
    public static void setup() {
        system = ActorSystem.create();
    }
 
    @AfterClass
    public static void teardown() {
        TestKit.shutdownActorSystem(system);
        system = null;
    }
 
    @Test
    public void testGreeterActorSendingOfGreeting() {
        final TestKit testProbe = new TestKit(system);
        final ActorRef helloGreeter = system.actorOf(Greeter.props("Hello", testProbe.getRef()));
        helloGreeter.tell(new WhoToGreet("Akka"), ActorRef.noSender());
        helloGreeter.tell(new Greet(), ActorRef.noSender());
        Greeting greeting = testProbe.expectMsgClass(Greeting.class);
        assertEquals("Hello, Akka", greeting.message);
    }
}
  • akka.test.javadsl.TestKit junit를 이용하여 테스트 케이스를 작성을 할수 있다.


'Programing > Akka' 카테고리의 다른 글

Akka Stream을 이용한 Kafka Producer 개발  (0) 2018.06.02
Persistence Actor  (0) 2018.05.27
Akka Cluster  (0) 2017.10.22
Akka Actor  (0) 2017.06.25
Akka Actor Throttle  (0) 2017.06.24