Local Actor를 Remote Actor로 확장하는것은 아주간단한것을 알게되었습니다.

이제는 이 RemoteActor를 Router기능(예를들어 라운드로빈)으로 확장을 시도해보겠습니다.


시나리오

  1. ANODE를 UP
  2. 인사를 그대로 돌려주는 EchoActor2 작성
  3. ANODE는 h1~h3 까지 3가지의 동일한 액터가 있음
  4. BNODE를 UP
  5. BNODE는 ANODE에게 설정된 라우터로 메시지를 만개보내고 그결과를 비동기적으로 받음


수정된 메시지 구조체
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Akka.Actor;

namespace CommonActor
{

    public class Hello
    {
        public Hello(string message)
        {
            Message = message;
        }

        public string Message { get; private set; }
    }

    public class HelloReq
    {
        public HelloReq(string message)
        {
            Message = message;
        }

        public string Message { get; private set; }
    }

    public class EchoActor2 : ReceiveActor
    {
        protected int recCnt = 0;

        protected bool isLog()
        {
            if (recCnt < 10 || recCnt % 100 == 0)
                return true;
            else
                return false;
        }

        public EchoActor2()
        {
            Receive<Hello>(hello =>
            {
                recCnt++;
                if(isLog())
                    Console.WriteLine("Log: [{0} -> {1} ]: {2}", Sender,Self.Path , hello.Message);
                Sender.Tell(new HelloReq(hello.Message));
            });

            Receive<HelloReq>(hello =>
            {
                recCnt++;
                if (isLog())
                    Console.WriteLine("Log: [{0} -> {1} ]: {2}", Sender, Self.Path, hello.Message);                
            });
        }
    }

}




라우터기능으로 확장
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Akka;
using Akka.Actor;
using Akka.Event;
using Akka.Routing;
using CommonActor;
using Akka.Configuration;
using Akka.Cluster;
using Akka.Streams;
using Akka.Streams.Dsl;
using System.IO;
using Akka.IO;
using Akka.Streams.IO;

namespace ServiceB.STUDY
{
    public class RemoteTest
    {
        ActorSystem actorSystem;

        public void RunAll()
        {
            ConsoleKeyInfo cki;
            Console.WriteLine("====  SubTest선택");
            Console.WriteLine("1.Up ANODE");
            Console.WriteLine("2.Up BNODE");            

            cki = Console.ReadKey(true);

            switch (cki.Key)
            {
                case ConsoleKey.D1:
                    remoteNodeUP_A();
                    break;
                case ConsoleKey.D2:
                    remoteNodeUP_B();
                    break;                
            }
        }

        public void remoteNodeUP_A()
        {
            createActorSystem("ANODE", 7000);
            actorSystem.ActorOf<EchoActor2>("hello");
            actorSystem.ActorOf<EchoActor2>("h1");
            actorSystem.ActorOf<EchoActor2>("h2");
            actorSystem.ActorOf<EchoActor2>("h3");
        }

        public void remoteNodeUP_B()
        {
            createActorSystem("BNODE", 7001);
            var remoteHello = actorSystem.ActorSelection("akka.tcp://ANODE@127.0.0.1:7000/user/hello");
            var props = Props.Create<EchoActor2>().WithRouter(FromConfig.Instance);
            var routerActor = actorSystem.ActorOf(props, "workers");
            var receivedActor = actorSystem.ActorOf<EchoActor2>("hello");

            for (int i = 0; i < 10000; i++)
            {
                routerActor.Tell(new Hello("i'am BNODE idx:" + i), receivedActor);
            }
            
        }



        public void createActorSystem(string systemName , int port)
        {
            string strCfg = @"akka {
            actor{
                provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
                deployment = {
                    /workers{
                        router = round-robin-group
                        routees.paths = [""akka.tcp://ANODE@127.0.0.1:7000/user/h1"",""akka.tcp://ANODE@127.0.0.1:7000/user/h2"",""akka.tcp://ANODE@127.0.0.1:7000/user/h3""]
                    }
                }
            }
            remote {
                helios.tcp {
                    port = " + port + @" #bound to a specific port
                    hostname = 127.0.0.1
                }
            }            
            }";

            var baseConfig = ConfigurationFactory.ParseString(strCfg);

            actorSystem = ActorSystem.Create(systemName, baseConfig);

        }
        
    }
}


  • No labels