Versions Compared

Key

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

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

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

Image Modified

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

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

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

액터 구현

하이패스 게이트

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

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


현금정산소 게이트

Code Block
languagec#
themeEmacs
        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}");
            });
        }


액터 성능전략 적용

라우터구성

Code Block
languagec#
themeEmacs
	actor.deployment {
		/highpass-gate-pool {
			router = round-robin-pool
			nr-of-instances = 3
		}

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

...

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

스레드풀 구성

Code Block
languagec#
themeEmacs
# 기본 스레드 풀 사용 처리속도가 빨라 동시 처리량이 작게 필요한 경우
fast-dispatcher {
	type = Dispatcher
	throughput = 2
}

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

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

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

위 값에대한 최적값은 트래픽의 패턴에 따라 최적값을 찾아야하며, 중요한것은 성능에따라 분리해야한다란것이다.

일반적으로 액터 동시처리능력은 throughput에의해 결정되며 100이상의 값을 충분히 커버한다.

위와 같이 분리한 이유는, 성능이 느린 액터로 인해 동시 처리능력이 충분히 빠른 액터도 대기가 걸릴수 있기때문이다.

즉 동시처리 전체 성능 10이란것을 현금 게이트가 다 점유를 한다고하면, 하이패스에 처리되는 메시지 자체가

대기에 걸릴수 있으며 이것은 우리가 원하는 성능이 아니다.

...

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

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

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

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


액터 생성코드

Code Block
languagec#
themeEmacs
            services.AddAkkaActor<HigPassGateActorProvider>((provider, actorFactory) =>
            {
                var actor = actorFactoryAkkaLoad.RegisterActor(
	"highpass",
	actorSystem.ActorOf(Props.Create<HigPassGateActor>Create<HighPassGateActor>()
                    			.WithDispatcher("fast-dispatcher")
                    			.WithRouter(FromConfig.Instance), 
			"highpass-gate-pool");
                return () => actor;
            });

            services.AddAkkaActor<CashGateActorProvider>((provider, actorFactory) =>
            {
                var actor = actorFactoryAkkaLoad.RegisterActor(
	"cashpass",
	actorSystem.ActorOf(Props.Create<CashGateActor>()
                    			.WithDispatcher("slow-dispatcher")
                    			.WithRouter(FromConfig.Instance), 
			"cashpass-gate-pool");
                return () => actor;
            });

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

변경 소스 : https://github.com/psmon/AkkaForNetCore/commit/b24003bf16289e171111057174a970c9e45ef2ed지금 까지 설정한 내용이 항상 최적화된 상태로 작동됨을 보장할수는 없다. 

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