이장을 통해 추가적으로 알게 되는것

  • 액터에 고급 스레드 프로그래밍에서 사용되는 튜닝 옵션 사용하기
  • 액터의 성능을 각각 다르게 설정하기
  • 리모트로의 확장 가능성

메시징(유입차량)에따른 톨게이트 구현은 , 트래픽 처리연마를 위한 좋은 샘플입니다.

구현하려고 하는 톨게이트 모델

  • 하이패스와 현금게이트 비율은 3:7이며 비율 조정이 유연해야함 - 실세계는 큰 공사가 필요함
  • 하이패스는 기달림이 없음 - 실세계는 30km이하로 저속운행
  • 현금 게이트는 1~10초 랜덤한 대기발생 - 실세계는 정산원의 능력과 운전자의 능력이 복합적으로 반영됨
  • 동일 Type게이트에서 공평한 대기 분배가 이루어지고 Type이 다른것의 성능 차이는 감수해야함 - 실 세계는 줄을 잘서거나 ,교통법규를 준수하지 않으면  빠르게 통과할수도 있음 

액터 구현

하이패스 게이트

        public HigPassGateActor()
        {
            id = Guid.NewGuid().ToString();
            logger.Info($"하이패스 액터 생성:{id}");

            ReceiveAsync<string>(async msg =>
            {
                //하이패스는 그냥 지나가면됨
                logger.Debug($"{msg}");
            });
        }


현금정산소 게이트

        public CashGateActor()
        {
            rnd = new Random();

            id = Guid.NewGuid().ToString();
            logger.Info($"현금정산게이트 액터 생성:{id}");

            ReceiveAsync<string>(async msg =>
            {
                //현금정산에 걸리는시간 1~10초                 
                int delay = rnd.Next(1000, 10000);
                await Task.Delay(delay);
                logger.Debug($"{msg}-{delay}");
            });
        }


액터 성능전략 적용

라우터구성

	actor.deployment {
		/highpass-gate-pool {
			router = round-robin-pool
			nr-of-instances = 3
		}

		/cashpass-gate-pool {
			router = smallest-mailbox-pool
			nr-of-instances = 7
		}
	}

분배처리를 위해 가장 일반적으로 라운드 로빈을 사용한다. 라운드 로빈은 처리 시간이 빠르고 일정할때

가장 심플하고 많이 사용되는 분배처리 방식이다. 하이패스 게이트에서는 무난하게 적용해도 된다.

하지만 현금정산소의 경우?  완료시간에 걸리는 시간은 운전자의 역량, 정산담당자의 빠른 처리능력 복합적으로 적용되며

완료시간이 오래걸릴 뿐더러 , 처리 시간이 불규칙적이다. 

그래서, Akka에서 제공하는  Smallest-mailbox의 라우터를 이용할수 있으며 적합한 방식이다. 

  • RoundRobin : 단순하게 순차적으로
  • Smallest-MailBox : 대기열이 적은곳으로


Akka에서는 유용한 몇가지 라우터를 제공하며 이용할수 있습니다.

라우터에 대한 심화학습 : https://getakka.net/articles/actors/routers.html

스레드풀 구성

# 처리속도가 빨라 동시 처리량이 작게 필요한 경우
fast-dispatcher {
	type = Dispatcher
	throughput = 2
}

# 처리속도가 느려 동시 처리량 확보가 필요한 경우(8번째 동시처리는 7번째 동시처리중 하나가 끝날때를 기다림)
slow-dispatcher {
	type = Dispatcher
	throughput = 7
}

스레드 풀까지 고려한 설정을 일반적으로 할 필요는 없지만, 더 깊이있는 최적화를 한다고하면

위와같이 메시지 처리에 사용되는 스레드를 분리할수 있고 최적화 할수 있다.

라우터 설정이 스케일 아웃을 위한 기능이라고 한다고하면, Dispatcher 를 통한 스레드 효율성 전략은

스케일 업(단일 노드가 최대로 처리할수 있는능력)과 관련이 있습니다.

스레드가 무조건 많다고 많이 처리할수 있는것이 아니기때문에 , 최적화값을 찾아내는것은 어려운일중에 하나다

더 자세한 심화학습을 하고자 한다면 다음 문서 참고 : https://doc.akka.io/docs/akka/current/dispatchers.html


액터 생성코드

AkkaLoad.RegisterActor(
	"highpass",
	actorSystem.ActorOf(Props.Create<HighPassGateActor>()
			.WithDispatcher("fast-dispatcher")
			.WithRouter(FromConfig.Instance),
			"highpass-gate-pool"
));

AkkaLoad.RegisterActor(
	"cashpass",
	actorSystem.ActorOf(Props.Create<CashGateActor>()
			.WithDispatcher("slow-dispatcher")
			.WithRouter(FromConfig.Instance),
			"cashpass-gate-pool"
));

라우터 전략과 각 라우티에 사용된 액터에 스레드 사용전략을 복합적으로적용한 코드

지금 까지 설정한 내용이 항상 최적화된 상태로 작동됨을 보장할수는 없다. 

메시지를 분산처리 해야하는 네트워크 환경에서 튜닝을 할수 있냐? 없냐? 의 차이는 아주 크다. 



  • No labels