Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

시나리오 기반 부하테스트 적용 #4

Merged
merged 4 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
},
"dependencies": {
"@types/fluent-ffmpeg": "^2.1.27",
"artillery": "^2.0.22",
"artillery-engine-socketio-v3": "^1.2.0",
Comment on lines +54 to +55
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

서버 폴더의 package.json에도 동일하게 설치가 되었네 두 번 설치한건가?
일단 깃에선 취소해야할 것 같습니다

"concurrently": "^9.1.0",
"fluent-ffmpeg": "^2.1.3"
}
Expand Down
2 changes: 2 additions & 0 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
"@types/fluent-ffmpeg": "^2.1.27",
"@types/jest": "^29.5.14",
"@types/socket.io": "^3.0.2",
"artillery": "^2.0.22",
"artillery-engine-socketio-v3": "^1.2.0",
"aws-sdk": "^2.1692.0",
"bcrypt": "^5.1.1",
"cache-manager": "5.2.3",
Expand Down
39 changes: 18 additions & 21 deletions server/test/load/http-test.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
config:
target: "http://localhost:3000"
target: 'http://localhost:3000'
processor: './processor.js'
Comment on lines +2 to +3
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

배포 서버에도 살짝만 해보면 좋을 것 같아요

phases:
- duration: 10
arrivalRate: 200 # 초당 20명의 가상 사용자 생성

- duration: 60
arrivalRate: 2 # 초당 2명 = 분당 120명
name: '일반 부하'

# 피크 시간대 (전체 사용자의 약 70-80%)
- duration: 120
arrivalRate: 6 # 초당 6명 = 분당 360명
name: '피크 부하'

# 안정화 (전체 사용자의 약 50%)
- duration: 100
arrivalRate: 4 # 초당 4명 = 분당 240명

scenarios:
- name: "API Test"
- name: 'Stream Test'
flow:
# GET 요청 테스트
- get:
url: "/api/music/ab9eff15-869b-4737-9abe-b544875579d7/playlist.m3u8"

# # POST 요청 테스트
# - post:
# url: "/api/posts"
# json:
# title: "Test post"
# content: "This is a test content"

# 응답 확인 및 변수 저장
# - get:
# url: "/api/posts/{{ postId }}"
# capture:
# - json: "$.id"
# as: "postId"
url: '/api/music/c0fc932e-da70-4388-9ab6-93d69334f458/playlist.m3u8'
afterResponse: 'processM3U8'
Comment on lines +22 to +23
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 그냥 이렇게 함수를 불러오네 신기하네

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

artillery에서 일반 js 함수를 불러올 수 있다니... 따봉

51 changes: 51 additions & 0 deletions server/test/load/processor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const debug = require('debug')('processor:m3u8');
const axios = require('axios');

async function processM3U8(requestSpec, response, context, ee) {
debug('Starting M3U8 processing');
try {
if (!response || !response.body) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional Chaining 을 피드백 하려다 js 파일인 걸 보고 납득!

debug('Response or body is empty');
return;
}

const m3u8Content = response.body;
const lines = m3u8Content.split('\n');
const tsUrls = [];

lines.forEach((line) => {
if (
line.includes('/api/music/') &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

정규식을 쓰면 더 간단하게 해결될 것 같음!
물론 이 방식이 더 직관적인 것은 맞습니다~

line.includes('/playlist') &&
line.endsWith('.ts')
) {
tsUrls.push(line.trim());
}
});

debug(`Found ${tsUrls.length} ts URLs`);
if (tsUrls.length === 0) {
debug('No .ts files found');
return;
}

for (const url of tsUrls) {
try {
const fullUrl = `http://localhost:3000${url}`;
debug(`Requesting TS file: ${fullUrl}`);
const response = await axios.get(fullUrl);
debug(`TS file downloaded: ${url}, status: ${response.status}`);
} catch (error) {
debug(`Failed to download ${url}: ${error.message}`);
}
}

debug('M3U8 processing completed');
} catch (error) {
debug(`Error in M3U8 processing: ${error.message}`);
}
}

module.exports = {
processM3U8,
};
23 changes: 16 additions & 7 deletions server/test/load/socket-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,26 @@ config:
# 일단 로컬 환경 URL
target: 'http://localhost:3000'
phases:
# 10초 동안
- duration: 10
# 1초에 20명
arrivalRate: 20
- duration: 60
arrivalRate: 2 # 초당 2명 = 분당 120명
name: '일반 부하'

# 피크 시간대 (전체 사용자의 약 70-80%)
- duration: 120
arrivalRate: 6 # 초당 6명 = 분당 360명
name: '피크 부하'

# 안정화 (전체 사용자의 약 50%)
- duration: 100
arrivalRate: 4 # 초당 4명 = 분당 240명

engines:
socketio-v3:
transports: ['websocket']
timeout: 10000
variables:
# 원하는 roomId 설정
roomId: '7b82b46b-d705-48a5-9bc5-918ee1a124a0'
roomId: 'dec889e0-24a2-4d86-a36b-0c2fb9028e76'
scenarios:
- name: 'Chat room flow'
engine: socketio-v3
Expand Down Expand Up @@ -41,6 +50,6 @@ scenarios:
channel: 'vote'
data:
# 일단 노래 두 개가 있다고 가정하고, 랜덤 값 지정
trackNumber: "{{ $randomNumber(1,2) }}"
trackNumber: '{{ $randomNumber(1,2) }}'

- think: 30
- think: 30
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

think가 sleep 같은 기능을 하는 것으로 알고 있는데, 마지막에 think를 사용한 이유가 궁금합니다~

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 제가 한게 아니라서... @Kontae