Local Actor를 Remote Actor로 확장하는것은 아주간단한것을 알게되었습니다.
이제는 이 RemoteActor를 Router기능(예를들어 라운드로빈)으로 확장을 시도해보겠습니다.
시나리오
- ANODE를 UP
- 인사를 그대로 돌려주는 EchoActor2 작성
- ANODE는 h1~h3 까지 3가지의 동일한 액터가 있음
- BNODE를 UP
- 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); } } }