**이 글에는 node.js artillery 부하테스트와 관련은 있지만 얻을만한 지식이 전혀 없습니다.
**artillery 부하테스트를 위한 지식이 필요해서 검색을 통해 들어오신분이라면 뒤로가기를 눌러주세요.
현재 진행중인 프로젝트에서 Express기반 API 서버(5000포트)와 Socket.io 기반 소켓 서버(5001포트)로 돌아가는 서비스를 운영중이다. 채팅, 방, 검색, 이미지 업로드 그리고 이미지 리스트 뷰 등이 구현이 되어 있고 로컬환경은 물론이고 AWS환경에서도 구현한 기능에 한해서는 작동하는데 무리가 없는 상태이다.
소수의 사람들이 이용하면 문제는 없지만, 실제 서비스라면 다수의 사람들을 수용할 수 있어야한다.
이러한 부분이 대비가 되려면 트래픽이 존재하는 환경에서 서버가 어떻게 반응하는지, 현재 서버의 가용능력 한계점을 미리 파악하는 것이 중요하다. 알고자 하는 부분은 우선은 아래 세가지이고, 한계점을 확인하고 개선해보고 싶다.
1. 다수의 API request 를 보냈을 때, 서버의 반응과 어느정도의 request까지 수용 가능한지.
2. 어느정도의 유저들의 수용이 가능한지. (소켓통신은 어느정도까지 가능한지)
3. Out of memory가 발생하는 point가 존재하는지.
실사용자를 모아서 테스트하는 것은 실질적으로 어렵기 때문에 node js 라이브러리 중 Artillery라는 라이브러리를 사용해 부하테스트를 해보기로 했다.
먼저 유저정보와 socket roomId가 담긴 CSV 파일을 생성하고 테스트 시나리오를 작성하여 적용했다. 시나리오는 다음과 같다.
1. 가상 유저가 처음에 로그인을 하고 방에 입장한다. 입장에 필요한 API 요청을 보낸다.
2. id1~id7 로 부여된 socket roomid에 join한다. (소켓서버는 같은 roomid에 join한 유저들에게 브로드캐스팅)
3. 각 유저들이 0.2초 간격으로 각 룸에 채팅을 친다. 가상유저는 약 120명 생성하여 사실상 120명이 0.2초간격으로 본인들이 들어간 방에 소켓통신을 보낸다.
4. 서버 입장에서는 약 120*7/sec회의 소켓통신을 받고 하고 * 7 만큼 해당 룸에 속하는 각각의 모든 유저들에게 emit(브로드 캐스팅)한다.
AWS 모니터링 CPU가 45퍼센트정도까지 치솟았다. 실제 서비스였다면 이 정도면 오토스케일링으로 로드밸런싱을 해야되는 수준이다..
그런데 artillery 작성한 테스트 시나리오대로 잘 작동하는지에만 신경쓰고 결과를 보니 테스트 계획을 잘 못 세운 것 같다.
그냥 많이 보내면 부하가 걸린다는 것 뿐 알아낼 수 있는 정보가 없다.
로컬이 아닌 실제 서버에서 다시 하고싶은데, 내가 이 테스트만하면 그날부터 뭔가 서버에 계속 이상이 생기고 팀원을 고생시켰다.
메인서버에서는 안했으면 좋겠다고 말해주었고 그 부분에 대해 리스크가 있음을 깨달았다. 추후 테스트용으로 서버를 새롭게 배포해보고 그곳에서 자유롭게 다양한 접근을 하는 것이 좋겠다.
잘 모르겠어서 추후 다시 테스트가 필요한 부분
1. EC2에 소켓과 서버가 같이 올라가 있는 상황이고 테스트 시나리오에 두 가지 요청을 무지성으로 많이 보내서, CPU 부하에 API콜의 영향과 , 소켓통신의 영향 비율이 어떻게 되는지 잘모르겠음.
2. 부하가 없는경우 소켓요청은 지연이 거의 없고 1ms 이하선을 유지하는데, socket emit rate를 엄청 많이 늘리는 경우에도 latency가 20ms정도에서 해결이 된다. 20ms정도면 사용자 입장에서 거의 문제가 없는게아닐까?
소켓통신은 생각보다 부하가 안걸리는 것 같은데 데이터가 string이고 node js 로 만들어진 서버이기 때문에 잘 소화를 해내는 것일까?
3. 2번째 테스트에서 EC2 서버의 swapdisk를 가득채운 것의 실체가 무엇일까?
테스트 서버 배포후 테스트 시나리오를 다시 작성해서 테스트를 해봐야 겠다. 부하테스트도 가이드라인이 있는 듯하다
https://ko.myservername.com/12-best-line-graph-maker-tools
config:
target: "https://jahunseo.site/"
phases:
- duration: 15
arrivalRate: 8
maxVusers: 200
name: 8 users in a challenge42
payload:
path: "test_file2.csv"
fields:
- "id"
- "email"
- "password"
- "nickname"
- "id1"
- "id2"
- "id3"
- "id4"
- "id5"
- "id6"
- "id7"
# order: sequence
scenarios:
- name: "Test_case_2"
engine: "socketio"
flow:
- log: "{{email}} socket connection 시도"
- log: "{{email}} login 시도"
- post:
url: "https://jahunseo.site/api/user/login"
json:
email: "{{email}}"
pwd: "{{password}}"
- think: 1
- get:
url: "https://jahunseo.site/api/user/challenges/ids"
# - log: "{{email}} Challenge-42 페이지 접근"
- get:
url: "https://jahunseo.site/api/challenge/42"
- get:
url: "https://jahunseo.site/api/chat/42"
# - log: "test"
- emit:
channel: "join"
data:
id: "{{id}}"
"challenges":
[
id: "{{id1}}",
id: "{{id2}}",
id: "{{id3}}",
id: "{{id4}}",
id: "{{id5}}",
id: "{{id6}}",
id: "{{id7}}",
]
- log: "{{email}} Challenge room 입장"
- loop:
- emit:
channel: "send_message"
data:
challengeId: "{{id1}}"
"user_nickname": "{{nickname}}"
"message": "소켓 채팅테스트 중입니다. {{$loopCount}}"
"time": "11월 29일 Test"
acknowledge:
match:
json: "response"
- think: 0.2
- emit:
channel: "send_message"
data:
challengeId: "{{id2}}"
"user_nickname": "{{nickname}}"
"message": "소켓 채팅테스트 중입니다. {{$loopCount}}"
"time": "11월 29일 Test"
acknowledge:
match:
json: "response"
- think: 0.2
- emit:
channel: "send_message"
data:
challengeId: "{{id3}}"
"user_nickname": "{{nickname}}"
"message": "소켓 채팅테스트 중입니다. {{$loopCount}}"
"time": "11월 29일 Test"
acknowledge:
match:
json: "response"
- think: 0.2
- emit:
channel: "send_message"
data:
challengeId: "{{id4}}"
"user_nickname": "{{nickname}}"
"message": "소켓 채팅테스트 중입니다. {{$loopCount}}"
"time": "11월 29일 Test"
acknowledge:
match:
json: "response"
- think: 0.2
- emit:
channel: "send_message"
data:
challengeId: "{{id5}}"
"user_nickname": "{{nickname}}"
"message": "소켓 채팅테스트 중입니다. {{$loopCount}}"
"time": "11월 29일 Test"
acknowledge:
match:
json: "response"
- think: 0.2
- emit:
channel: "send_message"
data:
challengeId: "{{id6}}"
"user_nickname": "{{nickname}}"
"message": "소켓 채팅테스트 중입니다. {{$loopCount}}"
"time": "11월 29일 Test"
acknowledge:
match:
json: "response"
- think: 0.2
- emit:
channel: "send_message"
data:
challengeId: "{{id7}}"
"user_nickname": "{{nickname}}"
"message": "소켓 채팅테스트 중입니다. {{$loopCount}}"
"time": "11월 29일 Test"
acknowledge:
match:
json: "response"
- think: 0.2
count: 300
id,email,password,nickname,id1,id2,id3,id4,id5,id6,id7
1,kjy@kjy.net,abcd1234,jinyoung,1,2,3,4,6,10,42
2,kjm@kjm.net,abcd1234,jongmin,1,2,3,4,6,10,42
3,kkh@kkh.net,abcd1234,kangho,1,2,3,4,6,10,42
4,sa@gmail.com,abcd1234,안녕,1,2,3,4,6,10,42
5,santoryu1118@gmail.com,abcd1234,산토류,1,2,3,4,6,10,42
9,santoryu1117@gmail.net,abcd1234,이재열짱짱맨,1,2,3,4,6,10,42
11,smokeman@gmail.net,abcd1234,정신호신정,1,2,3,4,6,10,42
13,sleepman@gmail.net,abcd1234,이재열은짱짱,1,2,3,4,6,10,42
15,signalsmoke@gmail.net,abcd1234,crypttest,1,2,3,4,6,10,42
18,smoke_forever@gmail.net,abcd1234,정신호,1,2,3,4,6,10,42
21,sino@gmail.net,abcd1234,신호정,1,2,3,4,6,10,42
54,sinos@gmail.net,abcd1234,쟈니,1,2,3,4,6,10,42
77,sinojung@gmail.net,abcd1234,산토류,1,2,3,4,6,10,42
84,santoryu1116@gmail.net,abcd1234,정신,1,2,3,4,6,10,42
85,sinojungg@gmail.net,abcd1234,정신호신,1,2,3,4,6,10,42
86,dkfjfe@naver.com,abcd1234,이재,1,2,3,4,6,10,42
87,fdfe@naver.com,abcd1234,구구구,1,2,3,4,6,10,42
88,asdf@naver.com,abcd1234,이재열열,1,2,3,4,6,10,42
89,santorini1118@gmail.com,abcd1234,산토리니,1,2,3,4,6,10,42
91,wkgjs0809@gmail.com,abcd1234,자허니,1,2,3,4,6,10,42
92,shinhojung814@gmail.com,abcd1234,정신호123,1,2,3,4,6,10,42
118,kjy2@kjy.net,abcd1234,쟈니,1,2,3,4,6,10,42
'프로젝트' 카테고리의 다른 글
로드 밸런싱 관련 읽을 거리 (0) | 2021.12.09 |
---|---|
나만의 무기만들기 중간회의 (0) | 2021.11.26 |
간단한 채팅구현 Socket.io (Node js) (0) | 2021.11.22 |
MYSQL TRIGER (0) | 2021.11.18 |
AWS S3 Client side에서 이미지 업로드하기 (0) | 2021.11.17 |