Versions Compared

Key

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

...

클러스터 구성하기도 전에, 단일노드에서 효율적 동시성 접근문제에 대해 많은 고민을 해야합니다.

Actor

액터의 기본철학은, 액터가 차지하는 보유하고 있는 상태 메모리 공간은 어느 다른 쓰레드혹은 동일한 액터에서도 자기자신의 속성을 접근할수 없다를 원칙으로 한다. 공간는 어느 액터 혹은 심지어 부모가 액터가 자식 액터의  속성도 접근할수 없습니다.

( Protected 는 자식이 접근할수 있다란 OOP의 상속 개념을 사용할수 없습니다.)

다시말해 액터내부에 일어나는 일은 어느 누구와도 '공유'되지 않으며 죽음의 칵테일에서  공유라는 속성을 제거함으로 멀티쓰레드와 관련된 문제의 대부분을 제거 하고 시작한다.

공유되지 않기때문에, 임계영역 처리를 위해  'lock' 'synchronized' 와 같은 부자연스러운 키워드가 필요없으며 어려운 스레드 모델을 사용해야할 필요가 없어집니다.

물론 이러한 Actor도 OOP로 설계가되었으나, 접근 방식의 중심점을 객체가 아닌 메시지를 통해 한다는점에서의 차이이며

이와 유사한 메시지 처리기를 수없이 만들어 왔을것입니다.

 배워야 되지 않는다는 의미는 아님,오히려

기존 방식의 어려운점을 알아야 더 잘활용할수 있습니다. 

하지만 멀티스레드 구현에 너무 집중하지말고 관련 스레드 모델 컨셉 정도만 익히는것으로 충분합니다.

비동기형 능동적 객체인 Actor를 어떻게  최적화해서 다중스레드로 관리할것인가의 문제는

ActorSystem이 해야할일이며, 개발코드와 분리하여 옵션화를 통한 튜닝의 문제입니다.   ( http://doc.akka.io/docs/akka/2.5.3/scala/dispatchers.html )메시지를 통해서만 상대에게 명령할수 있고 값을 알아낼수 있다란 단순한 방법만을 사용합니다.

예제를 통해 어떻게 작동되는지 살펴봅시다.

Code Block
languagec#
themeEmacs
titleActor 설계 코드
linenumberstrue
public class MyActor: ReceiveActor
{
  //Actor모델 에서는 안전한 동시성처리를 위해 어떠한 프로퍼티(속성)도 공유가 필요없음으로, 속성 접근제한에 priave만으로 충분합니다.
  private readonly ILoggingAdapter log = Context.GetLogger();
  private int state =0;

  public MyActor()
  {
    Receive<string>(message => {
      log.Info("Received String message: {0}", message);
      Sender.Tell(state );
    });
    Receive<SomeMessage>(message => {...});
  }
}

//코드 변경 최소로 옵션만으로 로컬,원격,클러스터등러등의 작동 선택 전략이 가능하다.
var remoteActor = system.ActorSelection("akka.tcp://MyServer@127.0.0.1:8001/user/someActor"); 

// 질의를 하던지?(Ask), 단지 말만한다던지?(Tell), 결과를 기다리던지(Result)? 
// 객체 접근 기반이아닌 메시지 전송기반의 인터페이스를 사용하는 조금더 추상화된 모델이다.
// Tell의 의미를 상세히 분석하면, 내가 한말에 결과값이 필요없으니 처리만해달라란 의미이며 
// 네트워크상의 의미로 수행결과가 있어도 어떠한 값을 리턴한다고 해도, 결과메시지 자체가 발송되지 않습니다.
var state = remoteActor.Ask("Hello").Result; 


...

이와같은 처리방식은 동일한 컨셉으로 로컬뿐아니라 리모트처리,분산처리등으로 확장이 될수가있다.


 메시지 전송에의해서만 , 동시성에대한 처리를하기때문에 네트워크로의 확장에 유연합니다.

Actor2는 MessageA 처리중, MessageB요청을 받게되며 처리후 다음 메시지를 처리합니다.

쓰레드 모델과 다른점은 Actor3는 MessageB를 요청하고 대기상태에 빠질필요가 없고

Actor2의 내부에서는 Lock자체가 필요가 없게됩니다처리를 하게되며, 이러한 방식은 리모트로의 전환시 구현체의 변경이 없음을 의미합니다.

액터는 메시징을 받는 스레드와,이것을 하니씩 꺼내에 순차적으로 처리하는 작업 스레드가 분리되어 있음으로

연속성을 보증함과 동시에, 작업이 블락킹으로 구현 되었다고 하더라도, 항상 메시지를 받을수 있습니다.

Actor2는 그 누구와도 자신의 상태에대한 메모리를 공유하지 않기때문에 상태변경에 필요한 속성의 Lock이 필요가 없습니다.


Note

액터의 특징을 살펴 보고자 반대편에 있는 OOP를 이용한 스레드 직접 제어의 단점을 예를 들었지만

액터 시스템도 Dispatcher 란 튜닝가능 객체가 스레드 풀을 이용을 하며, OOP로 작성된 추상화 객체입니다.

도메인 메시지 처리에 있어 스레드를 이용하는 OOP적 설계방식이 단순성을 유지하고 확장에 유연한 개발능력을 가지고 있는가?

스스로 질문을 던저볼수 있으며, 메시징 처리에 있어 동시성 처리를 포함한 다음 3가지 주제는  액터나 아카와 상관없는

공통주제로 , 액터를 연마하기전 추천 선행 자료입니다. 

...