Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Info

Actor로 설계된것은 원격으로 확장이 가능하기때문에 RemoteActor라는 객체는 존재하지 않습니다.

단지 로컬액터와 동일한 방식으로, 원격지 액터와 대화를 할수 있으며

직렬화,TCP 통신방식등은 몇가지 설정으로 변경가능하며 Akka에게 맞기면 됩니다.


사용준비조건

No Format
//메이븐 설정추가
<dependency>
  <groupId>com.typesafe.akka</groupId>
  <artifactId>akka-remote_2.12</artifactId>
  <version>${akka.version}</version>
</dependency>


//application.conf 설정 추가
akka {
  actor {
    provider = remote
  }
  remote {
    enabled-transports = ["akka.remote.netty.tcp"]
    netty.tcp {
      hostname = "0.0.0.0"
      port = 2552
    }
 }
}



// 로컬로 설계된 메시지,직렬화 상속받기
public class SomeMessage implements Serializable {
....}

...

  • 메이븐에 Remote추가 : netty를 비롯하여 원격통신에 필요한 몇가지 라이브러리가 포함됩니다.
  • 원격포트 설정 : 하나의 통신 포트에 수십만개의 액터를 등록하여 관리할수 있습니다. 그리고 이것은 스레드가아닌 힙에관리되기때문에 가볍습니다.
  • 로컬메시지 객체 직렬화하기 : 로컬에서만 작동가능한 메시지에 Serializable 상속을 받아, 단지 직렬화 가능한 객체를 전송을 하면됩니다.


컨셉

draw.io Diagram
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNameremoteactor
simpleViewerfalse
width
diagramWidth903
revision2

...

일반적으로 재접속 처리 문제를 신경쓸필요가 없습니다. ( 연결복구기능이 기본 탑재되며, 필요하면 장애시 재전송룰 적용가능)  


활용될수 있는 기능

  • A1,A3에 일어난일을 A2에게 모두보고하여 로그를 집합할수 있습니다. 
  • B1에서 일어난 일을 A2에게 보고하고 DB형님이 안바쁠때 변경사항을 알려줄수 있습니다.(DB 호출량제어가능)
  • 이미 존재하는 미들웨어에서 쌍반간 통신의 길을 뚫어줌으로, 관리요소추가(MQ시스템)없이 스스로 연락을 할수 있습니다.
  • 라운드로빈/브로드캐스트등 특수한 라우티이용도가능하며, 클러스터화 전환도 용이합니다.
  • 메시지기반으로 설계된 것은, RabbitMQ및 카프카와같은 외부 MQ 시스템과도 연동이 수월해집니다.

...

그럼 구현체가 얼마나 간단해졌는지 살펴보겠습니다.

서버 구현체

Code Block
languagejava
themeEmacs
public class TestActor extends UntypedAbstractActor{
    private final LoggingAdapter log = Logging
            .getLogger(getContext().system(), "TestActor");

    @Override
    public void onReceive(Object message) throws Exception {    	    	
    	if(message instanceof String) {	//String뿐만 아니라 모든 Java객체 통신가능
    		log.info("Incommessage {}", message);
    		sender().tell("너의 메시지에 응답을함", ActorRef.noSender());    		
    	}else {
    		log.info("Unhandle Message {}", message);    		
    	}    	
    }
}

//service1 이름으로 액터의 엔드포인트를 생성했습니다.
ActorRef testActor = system.actorOf(ext.props("testActor"),"service1");  //Service1이란 이름으로 TestActor를 생성함


사용측

Code Block
languagejava
themeEmacs
//엔드포인트를 통한 액터선택자
ActorSelection testActorRemote = system.actorSelection("akka.tcp://app@localhost:2552/user/service1");


//리모트를 통한 전송
testActorRemote.tell("발사후망각-응답필요없음",ActorRef.noSender() );  //ActorRef에 수신녀석을 지정하여 어떠한 결과를 받을수도 있습니다.

//응답이 동기적으로 필요한경우
CompletableFuture<Object> future1 =
		  ask(testActorRemote, "응답하라 1979", 1000).toCompletableFuture();

//너의 메시지에 응답을함 이란 메시지를 받음 -이해를 돕기위해 동기처리로 전환
String result = String.valueOf(future1.get());  

...