분산처리가능한 API호출을 하는 로드 테스트기를 만들어보자클러스터의 이해가 없어도, API호출 구현체만 작성하면 바로 활용가능하며
로드테스트 팀이있고, 툴을 구매할수 있으면 LoadRunner같은 전문 퍼포먼스 툴사용이 권장되나
이 문서의 목적은, 그럭저럭 쓸만한 분산처리 가능 심플 로드 테스트기를 직접 설계하고 구현해보는것입니다.
git : https://github.com/psmon/AkkaForNetCore - 구현이 다된상태이기때문에 자유롭게 활용가능합니다. -오픈유어소스 오픈유어 마인드
아키텍쳐
물리구성
구현Spec
- 각 노드는 모두 동일한 역활을 가지고 있으며,확장가능합니다. 클러스터가 되어 스스로 그룹형성을 하여 하나의 어플리케이션을 사용하는것처럼 이용가능합니다.
- 모두 동일한 역활을 하기때문에 어떠한 노드에게 명령을 해도, 라우터 논리구성에의해 분배가 됩니다.
- 각 1노드는 노드별 지정된 최고 능력치 설정이 가능합니다. ( ex>스레드풀내 작업자 300개 준비시킴)
- 각 노드의 최고능력치 합과는 별개로, 명령을 내릴시, 테스트에 필요한 동적 초당 TPS 제한지정이 가능합니다. ( 노드수 * 노드당능력치만큼 성능 확장이 가능합니다. )
- 네트워크레벨의 모니터보다 디테일한 도메인 기능에대한 세부 호출 카운팅 실시간 모니터링 가능합니다. ( 모니터링기능 탑재)
논리구성
별도의 분배기( L7,Nginx)가 필요없으며 자체 고성능 분배기를 가지고 있습니다.
라운드로빈외에 분산전략을 위해 다양한 분배기를 코드변경없이 설정만으로 선택이 가능합니다. - Akka 라우터
논리 코드 : https://github.com/psmon/AkkaForNetCore/tree/master/AkkaNetCore/Actors/LoadTest
주요 코드 액터설계
분산 컴퓨팅을위한 클러스터처리와 API호출을 하는 ApiWorkActor의 주요코드이다.
ApiCallSpec부분만 수정하여 로드테스트할 API호출이 가능하며, 시도 성공여부 카운팅이 가능하다.(모니터링대상 네이밍의 제약이없으며,Object별로 그룹핑이된다.)
//한꺼번에 명령가능한 액터로,TPS조절기가 빌트인 되어있습니다. public class TPSCommandActor : ReceiveActor { IActorRef batchActor; IActorRef throttleLimitWork; int seqNo; public TPSCommandActor(IActorRef workerPool) { seqNo = 0; // 1초에 한번씩 데이터를 방류하는 배치액터를 생성합니다. -실시간 비동기 FSM 패턴이 사용됨 batchActor = Context.ActorOf(Props.Create(() => new BatchActor(1))); // TPS를 조절하는 조절기를 생성합니다. throttleLimitWork = Context.ActorOf(Props.Create(() => new ThrottleLimitWork())); //배치액터와 조절기를 연결합니다. batchActor.Tell(new SetTarget(throttleLimitWork)); //조절기에 워커풀을 연결합니다.(라운드로빈풀) throttleLimitWork.Tell(new SetTarget(workerPool)); //기본 능력치를 5로 설정합니다. throttleLimitWork.Tell(5); //초당 처리능력 실시간 변경가능합니다. ReceiveAsync<int>(async limit => { throttleLimitWork.Tell(limit); }); // LoadTest 시작 명령은 이곳으로부터 출발합니다. // batchActor -> throttleLimitWork -> _worker ReceiveAsync<ApiCallSpec>(async msg => { msg.SeqNo = seqNo; //자동증가번호사용 //배치처리 Queue에 적재합니다. batchActor.Tell(new Queue(msg)); seqNo++; }); } protected override void PreStart() { Context.IncrementActorCreated(); } protected override void PostStop() { Context.IncrementActorStopped(); } }
멀티노드로 뛰우기
dotnet run --configuration Release --project AkkaNetCore --environment "Development" --port 5001 --akkaip 127.0.0.1 --akkaport 7100 --roles akkanet --akkaseed akka.tcp://actor-cluster@127.0.0.1:7100 --MonitorTool win dotnet run --no-build --configuration Release --project AkkaNetCore --environment "Development" --port 5002 --akkaip 127.0.0.1 --akkaport 5102 --roles akkanet,apiwork --akkaseed akka.tcp://actor-cluster@127.0.0.1:7100 --MonitorTool win dotnet run --no-build --configuration Release --project AkkaNetCore --environment "Development" --port 5003 --akkaip 127.0.0.1 --akkaport 5103 --roles akkanet,apiwork --akkaseed akka.tcp://actor-cluster@127.0.0.1:7100 --MonitorTool win
클러스터의 롤 지정을 통해 다른기능 수행이가능하며 첫번째 노드에 가입을 하여 클러스터가 구성된다.
무중단 배포를 위해 주키퍼와같은 도메인로직이 없는 시드노드를 추가 구성할수 있으나, 셀프조인도 가능합니다.
Akka 클러스터는 다음과 같은 특성을 가지고 있습니다.
- 분산처리 기능사용을위해 원격 위치를 알필요가 없다.
- 노드 확장을 위해 추가 설정이 필요하거나,다운타임을 가질필요가 없다. 노드를 줄일때도 마찬가지이다.
- 어플리케이션간 P2P 통신을 채택하였기 때문에, 병목지점이 없음으로 인스턴스 추가외에 확장에드는 비용은 Zero에 가깝습니다.
작동데모
윈도우 퍼포먼스 모니터링과 연동하였으며, 다양한 모니터링과도 연동이 가능하며
분산된 어플리케이션을 정확하게 TPS를 제어하여 Api테스트를 하는것이 이 프로젝트의 목적입니다.
테스트에 사용된 성능 옵션
- 확장 노드수 : 2
- 노드당 액터(work)수 : int workCount = 10;
컴퓨터의 성능에따라 최대 능력치 조절가능하며, API 동시호출 측정 효율수치를 셋팅합니다.(50~300에서 측정하여 타협)
이수치가 높다고 단일노드 능력치가 계속 높아지는것은 아니며 측정을통해 알아내어야합니다. - 암달의 법칙
마치며
클러스터 시스템과 분산처리에대한 이해를 높이기 가장 좋은 방법은, 개발자가 스스로 그 시스템을 구현하는것입니다.
MSA 구성의 설계와 구현의 능력이 따로가 아닌, 단순화하고 일치시키는 것이 이 문서의 활동 목표입니다.
참고링크: 이곳에 설명되어진 분산처리 기능은 다음 4가지 컨셉을 활용하였습니다.