Versions Compared

Key

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

ReceiveActor은 Actor의 기본 메시지 처리기가 정의된 기본 클래스이며

대부분의 기본 메시지처리는 ReceiveActor에서 가능합니다.


액터모델의 특징 요약

  • 동시및 분산 시스템작성을 위해 높은수준의 추상화제공
  • 개발자가 명시적 잠금처리및 스레드 관리 안해도됨
  • 이로인해 병렬 시스템 작성에 용이


ActorSystem 주요 메서드

  • Create : ActorSystem을 생성( 어플케이션당 하나 )
  • ActorOf : 자신의 레벨(탑)하위에 액터를 추가
  • ActorSelection : 접근경로 기반으로 액터를 선택함


Actor 메시지 전송 주요 메서드

  • Tell : 알리기만 하여, 결과값 신경안씀
  • Ask : 질의를 하며 요청에대한 결과값을 지켜봄(비동기), Result 조합시 기다림(동기처리)
  • Sender : Actor내에서 자신에게 메시지를 보낸, 발신자 ( 응답용도 )



Actor 정의(+메시지설계)

...


Code Block
languagec#
themeEmacs
titleReceiveActor
linenumberstrue
 
    public class SomeMessage
    {
        public string message { set; get; }
    }

    public class MyActor : ReceiveActor
    {        

        public MyActor()
        {
            Receive<string>(message => {
                Sender.Tell("RE:" + message);                
            });

            Receive<SomeMessage>(message => {
                Sender.Tell("RE:" + message.message);
            });
        }
    }


 Actor는, 메시지를  송수신을  송수신 정의하는 가장작은 객체의 정의 이며, 능동적 객체라고 볼수 있다.


Actor설계시 기본적으로 다음을 고려하면 된다고려한다. 이것은 마치 특정API 설계시 하는 고민과 똑같다.

...

위 정의 코드는 그러한 설계에대해 구현을 한것이며, 다음과 같은 스펙을 가진다.

  • message 문자열 오브젝트를 가진, SomeMessage 존재
  • 메시지를 받게 될시 , 접두어 "RE:" 를 붙여 해당 메시지를 그대로 돌려줌
  • 응답해야할 Type이 정해지지 않고 다양한 요청에 대해 다양한 Type으로 응답가능

 위 코드에서 생성자에서 ReceiveActor 생성자에서 , 패턴 Type 매칭하여 메시지 처리기가 가능한것은 , ReveiveActor의 Receive의 추상화덕분이며

IF문이나 스위치문없이 생성자에서 , 처리할 패턴별로 처리기가 등록이 가능한것은 C#의 문법지원때문인데

C# 언어학적으로 파악하고자 하면 ( 템플릿 람다 /함수형/ 델리게이트 특성) 참조하여 더 싶은 심화 학습이 가능합니다.


어쨋든, 우리의  아주 짧은 액터 메시지 처리기 설계가 끝이 났습니다.

액터 생성

...


Code Block
languagec#
themeEmacs
linenumberstrue
        protected void SomeTest1()
        {
            IActorRef myActor = actorSystem.ActorOf<MyActor>("myactor");
            Console.WriteLine(myActor.Ask("Hello Akka").Result);
        }

...

Heelo Akka란 메시지를 전송하여 그 결과값을 출력하는 예제입니다.

보낼수 있는 명령 Type

  • Ask : 결과값을 기대할때 사용합니다. 비동기로 수신하며, 동기처리시 .Result를 붙입니다. ( C#의 Async 프로그래밍 )
  • Tell : 결과값이  결과값이 필요 없을때 , 단지 전송만 하고 대기처리가 없습니다. 로직상 Tell에의해 어떠한 뒤늦은 결과값을 예상할수도 있습니다.


Child 액터 생성과

...

액터선택

...


자식 노드 생성

Code Block
languagec#
themeEmacs
linenumberstrue
            Receive<string>(message => {
                if (message == "createChild")
                {
                    Context.ActorOf<MyActor>("myChild");
                    Sender.Tell("Create Child Succed:myChild");
                }
                else
                {
                    Sender.Tell("RE:" + message);
                }
            });

문자열 수신부분을 수정을 하여,  createChild 란 문자열을 받을시 'myChild' 란 하위 노드의 액트를 액터를 생성하고

자식액트자식액터(하위노드) 의 생성을 반환하는 메시지를 응답하는 예제입니다.

...

이것을 작동시키는 코드는 아래와 같이 하면 되겠습니다.

특정노드를 선택하여, 자식 노드 동적으로만들고, 자식노드에게 메시지 보내기

Code Block
languagec#
themeEmacs
linenumberstrue
        protected void SomeTest2()
        {
            IActorRef myActor = actorSystem.ActorOf<MyActor>("myactor");
            Console.WriteLine(myActor.Ask("createChild").Result);
            Console.WriteLine(actorSystem.ActorSelection("/user/myactor").Ask("Hello Akka1").Result);
            Console.WriteLine( actorSystem.ActorSelection("/user/myactor/myChild").Ask("Hello Akka2").Result );
        }

...

myactor가 어떠한 이름(myChild) 하위 노드를 만들었다면 'user/myactor/myChild' 이렇게 계층화가 됩니다.

그리고 , 액트시스템은 액터시스템은 어떠한 액터라도 선택할수 있으며

actorSystem.ActorSelection( 액터주소).어떠한액션()  이러한 접근방식으로 메시지 전송이 가능합니다.

...


액터 생성 Factory화

Image Removed

잠시 실습없이, Actor를 접근하는 주소체계에대해 설명 드리겠습니다.  ActorPath는 총 4가지로 구분이 되며 

http의 RestAPI의 주소체계와 거의 흡사하다고 볼수 있습니다.

4요소

  • Protocol : AKKA를 사용하는 프로토콜임을 알림
  • ActorSystem : 주로 어플리케이션 하나의 이름으로, ActorSystem 최초 생성시 이름지정
  • Address : 네트워크 주소로 ip:port 로 표현
  • Path : 서비스 개발자가, 계층적으로 배치한 Actor 이름

여기서 의문을 가질수 있습니다. RestAPI와 흡사한데, 그냥 RestAPI를 사용할래~ 라구요

Image Removed

 주소체계와 사용법은 흡사하나, 애시당초 사용목적이 틀립니다.  위 예는 동일장비에서 액트 메시지만 처리능력 성능그래표이며

초당 50만메시지 처리가 가능합니다.  원격API뿐 아니라 , 로컬 시뮬레이션에 사용하기에도 충분한 동시적 처리능력을 가지고 있습니다.   

네트워크가 적용되면 네트워크 지연이 있어서, 위와같은 결과를 내지 못할테지만, ACTOR메시지 처리가 100배 이상 고성능일것으로 추측합니다. 

이것은 정확하게 ACTOR는 소켓 연결지속적 실시간처리이며 , RESTAPI가 전송1번에 연결을 맺고/끊고를 반복하는 프로토콜의 차이에 있습니다.

 AKKA의 주목적은 사용자에게 제공하는 REST를 걷어내는게 아니라, 미들웨어간 소통이 없는 서비스를 소통하게하여 DB 호출의 최소화

미들웨어간 RestAPI사용을 하였다면 변경으로 인한  성능향상상의 목적이 될것입니다.

다음 RemoteActor실습시 가상의 서비스 시나리오를 만들어 극명한 성능 차이를 프로파일링 비교해보겠습니다. 

...

Code Block
languagec#
themeEmacs
linenumberstrue
public class DemoActor : ReceiveActor
{
    private readonly int _magicNumber;

    public DemoActor(int magicNumber)
    {
        _magicNumber = magicNumber;
        Receive<int>(x =>
        {
            Sender.Tell(x + _magicNumber);
        });
    }

    public static Props Props(int magicNumber)
    {
        return Akka.Actor.Props.Create(() => new DemoActor(magicNumber));
    }
}

system.ActorOf(DemoActor.Props(42), "demo");

 자신의 액터 생성방식을 자신의 클래스내에서 정의하고 외부에 제공해주는것은 휼륭한 아이디어 입니다.



Info

Props

Actor생성을 위해 옵션을 지정하고, 이를 통해 액터 생성방법을 공유하기위한 구성클래스입니다.

몇가지 Props를 통한 다양한 액터 생성법


Props props1 = Props.Create(typeof(MyActor));
Props props2 = Props.Create(() => new MyActorWithArgs("arg"));
Props props3 = Props.Create<MyActor>();
Props props4 = Props.Create(typeof(MyActorWithArgs), "arg");