backend/Scala_Play_Akka

[Akka] Akka Document - Actor Architecture (1)

버리야 2018. 4. 22. 16:25
반응형
이 글은 원문 : https://doc.akka.io/docs/akka/current/guide/tutorial_1.html 글을 읽고 간략하게 정리한 내용입니다. (생략된 내용도 있습니다.)


Akka Version 2.5.12


Part 1: Actor Architecture


Akka를 사용하면 actor system 을 위한 인프라를 만들고 기본 동작을 제어하는 데 필요한 저수준 코드를 작성하지 않아도 된다. 

이를 이해하기 위해 코드에서 생성한 actor와 Akka가 생성하고 관리하는 actor 사이의 관계, actor 라이프 사이클 및 오류 처리를 살펴본다.


The Akka actor hierarchy


Akka의 actor는 항상 부모에게 속한다. 일반적으로 context.actorOf ()를 호출하여 actor를 만든다. 

"자립형 (freestanding)" actor를 만드는 대신, 새로운 actor를 자식으로 기존의 트리에 삽입한다. 

actor를 생성한 actor 는 새로 생성 된 자식 actor의 부모가 된다. 그런 다음 물어볼 수도 있다. 첫 번째 actor의 부모는 누구인지?


아래 그림에서와 같이 모든 actor에는 공통된 부모인 사용자 보호자가 있다. system.actorOf ()를 사용하여이 actor 아래에 새 actor 인스턴스를 만들 수 있다. Quickstart Guide에서 다룬 것처럼 actor 생성은 유효한 URL 인 참조를 반환한다. 따라서 예를 들어 system.actorOf (..., "someActor")라는 someActor라는 액터를 만들면 해당 참조에 /user/someActor 경로가 포함된다.



box diagram of the architecture


실제로 코드에서 actor를 만들기 전에 Akka는 이미 시스템에 세 개의 actor를 미리 만들었다. 

이러한 내장된 actor의 이름에는 보호자가 포함되어 있다. 이들은 자신의 경로에 있는 모든 child actor를 감독(supervise)하기 때문이다. 

guardian actor 는 다음을 포함한다 :


/ : root guardian 시스템에 있는 모든 actor의 부모이며 시스템 자체가 종료 될 때 마지막으로 멈추는 액터


/user : 모든 user 생성 actor의 부모 액터. Akka  라이브러리를 사용하여 생성 한 모든 actor는 앞에 /user 라는 상수 경로를 가진다.


/system : system guardian



actor 계층 구조를 보기 위한 가장 쉬운 방법은 단순히 Actor Ref 인스턴스를 출력하는 것이다. 

이 실험에서는 actor를 만들고 참조를 출력하고 이 actor의 자식을 만들고 그 참조를 출력한다. 

Hello World 프로젝트로 시작한다. 다운로드하지 않았다면 Lightbend Tech Hub에서 Quickstart 프로젝트를 다운로드하면 된다.


package com.lightbend.akka.sample

import akka.actor.{ Actor, Props, ActorSystem }
import scala.io.StdIn

class PrintMyActorRefActor extends Actor {
  override def receive: Receive = {
    case "printit" ⇒
      val secondRef = context.actorOf(Props.empty, "second-actor")
      println(s"Second: $secondRef")
  }
}

object ActorHierarchyExperiments extends App {
  val system = ActorSystem("testSystem")

  val firstRef = system.actorOf(Props[PrintMyActorRefActor], "first-actor")
  println(s"First: $firstRef")
  firstRef ! "printit"

  println(">>> Press ENTER to exit <<<")
  try StdIn.readLine()
  finally system.terminate()
}


메시지가 첫 번째 actor에게 작업을 요청하는 방법에 대해 보자. 

부모의 참조 firstRef를 사용하여 메시지를 보냈다. "firstRef ! "printit"  코드가 실행되면 출력에는 printit 메시지가 왔을때의 PrintMyActorRefActor의 case문이 실행되어 생성 된 첫 번째 actor 및 하위 참조가 포함된 출력 결과를 찍는다. 출력 결과는 다음과 같다.


First: Actor[akka://testSystem/user/first-actor#1053618476]
Second: Actor[akka://testSystem/user/first-actor/second-actor#-1544706041]


두 경로 모두 akka : // testSystem /으로 시작한다. 모든 액터 참조는 유효한 URL이므로 akka : //는 프로토콜 필드의 값이다.

다음으로 월드 와이드 웹과 마찬가지로 URL은 시스템을 식별한다. 이 예제에서 시스템의 이름은 testSystem이지만 다른 이름이 될 수 있다. 
여러 시스템 간의 원격 통신이 활성화 된 경우 URL의 이 부분은 호스트 이름을 포함하므로 다른 시스템이 호스트 이름을 네트워크에서 찾을 수 있다.

두 번째 액터의 참조에는 /first-actor/ 경로가 포함되어 있으므로 첫 번째 actor의 자식으로 식별한다.

actor 참조의 마지막 부분 인 #1053618476 또는 #-1544706041은 대부분의 경우 무시할 수있는 고유 한 식별자이다.

actor 계층 구조가 어떻게 생겼는지 이해한다면 궁금해 할 것이다. 왜 이 계층 구조가 필요한가? 그것은 무엇을 위해 사용되나?
계층 구조의 중요한 역할은 actor 라이프 사이클을 안전하게 관리하는 것이다. 다음으로 이것을 고려해보고 그 지식이 어떻게 더 나은 코드를 작성하는 데 도움이되는지 살펴보자.





반응형