관리 메뉴

HAMA 블로그

예제로 보는 아카(akka) - 8. 원격 액터 본문

Akka

예제로 보는 아카(akka) - 8. 원격 액터

[하마] 이승현 (wowlsh93@gmail.com) 2016. 10. 7. 10:14

- Scala 2.11 기반 

- Akka 2.4.11 기반 

Learning Concurrent Programming in Scala 참고 


원격 액터 

지금까지는 한 컴퓨터 안의 한 프로세스 안에서 실행되는 내용이었다.
여기서는 기존의 액터를 가지고 분산된 컴퓨터 상에 배치해서 실행해보자. 
Pingy 와 Pongy 라는 두개의 액터끼리 메세지를 보내고 받는 구현을 그대로 해볼것이다.

Sbt 에 의존성 추가

libraryDependencies += "com.typesafe.akka" %% "akka-remote" % "2.4.11"

별게 없다 akka-remote 의존성만 양쪽에 추가하면 끝.

A 컴퓨터 액터 생성 (Pingy)

import akka.actor._
import akka.event.Logging
import akka.util.Timeout
import akka.pattern.{ask, pipe}
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import com.typesafe.config.ConfigFactory

class Pingy extends Actor {
def receive = {
case pongyRef: ActorRef =>
implicit val timeout = Timeout(2 seconds)
val future = pongyRef ? "ping"
pipe(future) to sender

}
}

class Runner extends Actor {
val log = Logging(context.system, this)
val pingy = context.actorOf(Props[Pingy], "pingy")
def receive = {
case "start" =>
val path = context.actorSelection("akka.tcp://PongyDimension@192.168.1.35:24321/user/pongy") // 보낼 주소
path ! Identify(0)
case ActorIdentity(0, Some(ref)) =>
pingy ! ref
case ActorIdentity(0, None) =>
log.info("Something's wrong -- no pongy anywhere!")
context.stop(self)
case "pong" =>
log.info("got a pong from another dimension.")
context.stop(self)
}
}


object RemotingPingySystem extends App {

def remotingConfig(port: Int) = ConfigFactory.parseString(s"""
akka {
actor.provider = "akka.remote.RemoteActorRefProvider"
remote {
enabled-transports = ["akka.remote.netty.tcp"]
netty.tcp {
hostname = "192.168.1.148" // 자신 고유 주소 (보낼곳의 주소와는 다르다)
port = $port // 자신 고유 포트 (보낼 곳의 포트와는 다르다)
}
}
}
""")

def remotingSystem(name: String, port: Int) = ActorSystem(name, remotingConfig(port))

val system = remotingSystem("PingyDimension", 24567)
val runner = system.actorOf(Props[Runner], "runner")
runner ! "start"
Thread.sleep(20000)
system.terminate()
}

- 눈에 띄는 것은 액터시스템 만드는 방법이 좀 달라진건데 리모트 설정을 해준다.
   @ 포트설정
   @ host 설정 
   @ Remote프로바이더 설정
   @ netty tcp 를 이용

- actor 는 어플리케이션 로직은 완전 동일하며 보낼 액터를 찾는 방식이 액터셀력션(주소) 를 통해 찾고있다.

B 컴퓨터 액터 생성 (Pongy)

import akka.actor._
import akka.event.Logging
import com.typesafe.config.ConfigFactory


class Pongy extends Actor {
val log = Logging(context.system, this)
def receive = {
case "ping" =>
log.info("Got a ping -- ponging back!")
sender ! "pong"
context.stop(self)
}
override def postStop() = log.info("pongy going down")
}


object RemotingPongySystem extends App {

def remotingConfig(port: Int) = ConfigFactory.parseString(s"""
akka {
actor.provider = "akka.remote.RemoteActorRefProvider"
remote {
enabled-transports = ["akka.remote.netty.tcp"]
netty.tcp {
hostname = "192.168.1.35" // 자신 고유 주소

port = $port // 자신 고유 포트
}
}
}
""")

def remotingSystem(name: String, port: Int) = ActorSystem(name, remotingConfig(port))

val system = remotingSystem("PongyDimension", 24321)
val pongy = system.actorOf(Props[Pongy], "pongy")
Thread.sleep(30000)
system.terminate()
}

- Pingy 와 마찬가지로 액터시스템을 리모트설정으로 생성 해준다. 
- actor 에서 별달리 추가되는 내용이 없다. 엄청 단순해졌다.


좀 더 실용적인 예제는   akka-sample-remote-scala 를 참고 하시라
원격통신이 너무 쉬워졌으니 이제 나머지 두뇌 회전은 멋진 분산 비지니스 로직 처리에 집중 할 수 있게 되었다.

Comments