K6 를 활용한 웹소켓 부하 테스트
K6 를 활용한 웹소켓 부하 테스트
이런 말이 있습니다.
“나를 죽이지 못하는 고통은 나를 더 강하게 만든다.” - 프리드리히 니체
견고한 소프트웨어를 만들기 위해서는 부하 테스트를 통해서 약점을 찾아야 합니다. 롱쿼리, 병목이 되는 응답 등을 여러 시나리오를 통해서 발견하고, 개선할 수 있어야 합니다.
ubuntu 환경에서 docker 를 이용해서 k6 부하 테스트를 해보겠습니다. k6 를 사용하는 이유는 다음과 같습니다
- js 로 fe 에서 요청을 보내는 형식과 유사하게 테스트를 작성할 수 있다.
- 웹 소켓 프로토콜을 지원한다.
- grafana 에서 만들었기에, grafana 템플릿이 다양하고, 문서가 잘되어 있다.
docker 로 k6 설치
1
2
3
docker pull grafana/k6
test 를 수행할 script 코드 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import ws from 'k6/ws';
import { check } from 'k6';
const FIXED_HEADER_LENGTH = 64;
let fixedHeader = new ArrayBuffer(FIXED_HEADER_LENGTH);
let headerBytes = new Uint8Array(fixedHeader);
let conneceted = false;
let waplAuth = null;
let stack = [];
function connectWebSocketAndTest() {
ws.connect(url, {}, function(socket) {
conneceted = true;
console.log('WebSocket connection opened');
socket.on('open', function() {
console.log('Connection opened');
init(socket);
});
socket.on('message', function(e) {
// socket 에서 수행할 테스트
const jsonObjects = parseMultipleJSONs(decodeData);
jsonObjects.forEach((obj) => {
const textContent = JSON.stringify(obj, null, 2) + "\n\n";
stack.push(textContent);
});
console.log(stack.join(""));
console.log("Response JSON objects: ", jsonObjects);
const varHeader = jsonObjects[0];
// 응답 결과 검증
check(varHeader, {
'status is OK': (r) => r && (r.statusCode === 'OK' || r.statusCode === 200)
});
});
socket.on('close', function() {
conneceted = false;
stack = [];
console.log('Connection closed');
});
});
}
async function init(socket) {
connect();
await sendMessage(socket);
}
export const options = {
stages: [
{ duration: '2m', target: 400 }, // 테스트 수행할 stage 설정 400 명의 vuser 로 2 분간 테스트
{ duration: '10m', target: 0 }, // scale down. Recovery stage.
],
};
export default function () {
connectWebSocketAndTest();
}
위의 test.js 코드를 인자로 docker 명령어를 수행합니다.
1
2
3
4
docker run -i --rm -v $(pwd):/scripts -w /scripts grafana/k6 run /scripts/test.js
test 결과 모니터링 및 시각화
테스트를 수행해도 결과가 나오지만, 시각화를 하면 더욱 이해하기 좋습니다. influxDb 로 데이터를 보내고, grafana 를 통해서 그래프로 만들겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
version: "3.7"
services:
influxdb:
image: bitnami/influxdb:1.8.5
container_name: influxdb
ports:
- "8086:8086"
environment:
- INFLUXDB_ADMIN_USER_PASSWORD=bitnami123
- INFLUXDB_ADMIN_USER_TOKEN=admintoken123
- INFLUXDB_HTTP_AUTH_ENABLED=false
- INFLUXDB_DB=myk6db
volumes:
- influxdb_data:/bitnami/influxdb
grafana:
image: bitnami/grafana:latest
container_name: grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
depends_on:
- influxdb
volumes:
influxdb_data:
influxdb 및 grafana 를 설치해줍니다.
1
2
3
docker run -i --rm -v $(pwd):/scripts -w /scripts grafana/k6 run --out influxdb=http://influxdb:8086/myk6db /scripts/test.js
이제, 테스트를 수행하면 그 결과 지표가 influxdb 로 들어갑니다. influxdb 는 docker container 로 띄웠기에, grafana/k6 내부에서 influxdb 에 접근할 수 있도록 방화벽 확인을 잘 해줍시다.
이후, grafana 에서 influxdb 를 datasource 로 설정한 후, 각종 metrics 를 바탕으로 그래프를 만들어주면 됩니다. 다만 아직 websocket 에 대해서는 grafana template 이 잘 없어서 직접 시각화 대시보드를 구성해줘야 합니다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.