회사에서 국가 성능 테스트에 관한 업무가 있었다.
내가 맡은 부분은 socket의 동접자를 10000명이상 감당한 서버인가 테스트 해보는 것이었다.
동접자를 테스트해본 결과 5000명까지는 로컬(맥)에서 vuser(가상의 user)를 생성 가능했지만, 이게 5000명이 넘어가는 순간부터는 계속해서 socket error를 냈다.
오토 스케일링도 충분히 걸어놨음에도 불구하고 socket이 에러가 나자, 이게 과연 socket 서버의 문제인지 로컬 맥북으로만 테스트를 감당할거라고 생각한 나의 판단의 문제인지 헷갈리기 시작했다.
그래서 팀장님께 자문을 구해 artillery distributed test 툴을 도입하였다.
https://www.artillery.io/docs/load-testing-at-scale/aws-fargate
Artillery는 artillery cli로 관련 명령을 넣으면 aws-sdk를 사용해 부하테스트용 Fargate 서버들을 생성해 클라이언트의 역할을 수행한다.
AWS SDK
AWS Fargate를 사용하여 부하 테스트를 실행할 때 Artillery는 이를 최대한 원활하게 만들려고 노력합니다.
부하 테스트 번들링
Artillery는 테스트 스크립트를 분석하고 모든 종속성을 번들로 패키징하여 테스트를 실행하는 Fargate 컨테이너에서 사용할 수 있도록 합니다.
AWS 리소스 생성
필요한 경우 Artillery는 테스트를 실행할 Fargate 컨테이너와 Fargate 클러스터에 대한 IAM 역할을 생성합니다.
부하 generator 생성
Artillery는 다수의 Fargate 컨테이너( --count 플래그로 직접 사용자가 몇개의 부하를 전송할 서버를 띄울지 지정)를 가동하고 모든 컨테이너에 테스트 번들을 배포한 후 모든 컨테이너가 동기화되어 사용 가능해질 때까지 기다립니다.
부하 생성기의 결과 집계
로드 생성기가 실행되면 Artillery는 개별 컨테이너의 보고서를 집계하고 이를 통계적으로 올바른 방식으로 집계하여 사용자에게 제공합니다.
AWS 리소스 정리
테스트가 완료되면 Artillery는 더 이상 필요하지 않은 AWS 리소스를 제거합니다.
- 테스트 번들을 저장한 s3 버킷
- 테스트 실행하는 Fargate 컨테이너와 Artillery CLI 간의 통신을 위한 SQS 대기열
CreateOrGetECSRole
CreateECSPolicy
iam:CreateServiceLinkedRole
iam:PassRole
SQSPermissions
SQSListQueues
ECSPermissionsGeneral
ECSPermissionsScopedToCluster
ECSPermissionsScopedWithCondition
S3Permissions
secretsmanager:GetSecretValue
# ssm 권한
ssm:PutParameter
ssm:GetParameter
ssm:GetParameters
ssm:DeleteParameter
ssm:DescribeParameters
ssm:GetParametersByPath
# ec2 describe 권한
ec2:DescribeRouteTables
ec2:DescribeVpcs
ec2:DescribeSubnets
실행 중인 테스트는 AWS 콘솔에서만 중지할 수 있습니다.
AWS Fargate 테스트 실행이 시작되면 AWS 콘솔 또는 AWS CLI를 통해 Fargate 작업을 중지해야만 테스트를 중지할 수 있습니다.
향후에는 Artillery CLI에 현재 실행 중인 테스트를 중지하는 기능을 추가할 예정입니다.
artillery run-fargate --region {region} --count 3 ./test.yaml --output report.json
필자는 npm으로 artillery를 다운받아 실행했는데 앞에 npx 붙여서 실행해도 잘 된다.
default VPC에서 퍼블릭 서브넷을 찾을 수 없습니다.
1. default vpc가 없는 경우
aws 콘솔에서 vpc -> 기본 vpc 설정여부를 확인해서 default vpc로 설정이 되어있는지 확인해야한다. aws에서 이미 생성된 vpc를 기본 vpc로 변경하는 방법은 없는것 같다.
(필자는 성능 테스트 용도라 빠르게 지울 생각으로 그냥 하나 생성했다.)
그리고 혹여 vpc에 public subnet이 없을 경우 테스트 실패하니 public subnet 설정을 해준다.
<기타 잡담>
1. think를 활용한 실제 동접자 만들기
scenarios:
-engine: socketio-v3
flow:
- emit:
namespace: "/"
channel: "connection"
# think 설정하면 소켓이 바로 끊어지지 않고 160초 동안 connection을 유지
# 이 설정을 하면 동접자를 만들 수 있음.
- think: 160
안녕하세요! 소켓.io 테스트 자료를 찾고있었는데 좋은 글 감사합니다. think로 동접자 처리를 할수있군요...! 혹시 소켓 테스틋할때 v2 사용하면 안돼는 이유가 있나요?