
๋ค์ด๊ฐ๋ฉฐ
๋ถํ ํ ์คํธ๋ ์์คํ ์ ์ต๋ ์ฒ๋ฆฌ๋(TPS), ์์ ์ฑ, SLA(์๋น์ค ์์ค ๊ณ์ฝ) ๋ฐ SLO(์๋น์ค ์์ค ๋ชฉํ)๋ฅผ ๊ฒ์ฆํ๋ ์ค์ํ ๊ณผ์ ์ ๋๋ค. ์ด๋ฒ ๊ธ์์๋ ์ฝ์ํธ ์์ฝ ์๋น์ค์์ ์ ์ ํ๋์ ๊ธฐ๋ฐ์ผ๋ก ํ ๋ ๊ฐ์ง ์๋๋ฆฌ์ค๋ฅผ ์ค์ฌ์ผ๋ก, Docker ํ๊ฒฝ์์ ์์์ ์กฐ์ ํ๋ฉฐ ์ฑ๋ฅ ํ ์คํธ๋ฅผ ์ํํ ๋ด์ฉ์ ์ ๋ฆฌํด๋ณด๊ฒ ์ต๋๋ค.
1. ํ ์คํธ ์๋๋ฆฌ์ค ์ค๊ณ
์ ์ ์ ํ๋์ ๊ธฐ๋ฐ์ผ๋ก ๋ ๊ฐ์ง ํ ์คํธ ์๋๋ฆฌ์ค๋ฅผ ์ค๊ณํ์ต๋๋ค. ๊ฐ๊ฐ์ ์๋๋ฆฌ์ค๋ ์์คํ ์ ์๋ก ๋ค๋ฅธ ์ํ(์ ์ ๋นํ์ฑ/์ ์ ํ์ฑ)๋ฅผ ํ ์คํธํ๊ธฐ ์ํด ์ ์ ํ์ต๋๋ค.
- ์๋๋ฆฌ์ค 1 : ์ ์ ๋๊ธฐ์ด ๋นํ์ฑ
- ๋ชฉํ: ๋๊ธฐ์ด ์์คํ ์์ ํ ํฐ ๋ฐ๊ธ ๋ฐ ์ํ ์กฐํ์ ์ฒ๋ฆฌ๋ ์ธก์
- ํ๋ ํ๋ฆ
- ์ ์ ๊ฐ ๋๊ธฐ์ด ํ ํฐ ๋ฐ๊ธ ์์ฒญ
- ์ ์ ๊ฐ 1์ด ๊ฐ๊ฒฉ์ผ๋ก ํ ํฐ ์ํ ์กฐํ
- ์ค์
- ๋๊ธฐ์ด ์์คํ ์ ์์ ์ฑ ํ์ธ
- ๋จ์ ์กฐํ ์์ ์์์ ์ต๋ TPS ๋ฐ ํ๊ท RPS ์ธก์
- ์๋๋ฆฌ์ค 2 : ์ ์ ๋๊ธฐ์ด ํ์ฑ
- ๋ชฉํ: ์ฝ์ํธ ์์ฝ ๋ฐ ๊ฒฐ์ ๊ณผ์ ์ ์ฒ๋ฆฌ๋ ์ธก์
- ํ๋ ํ๋ฆ
- ์ ์ ๊ฐ ์ฝ์ํธ ์ ๋ณด๋ฅผ ์กฐํ
- ์ ์ ๊ฐ ํน์ ํ์ฐจ์ ์ข์ ์ ๋ณด๋ฅผ ์กฐํ
- ์ ์ ๊ฐ ์ข์ ์์ฝ ์์ฒญ
- ์ ์ ๊ฐ ์์ฝ ๊ฒฐ์ ์์ฒญ
- ์ค์
- ๋ณต์กํ ํธ๋์ญ์ (์์ฝ ๋ฐ ๊ฒฐ์ ) ์ฒ๋ฆฌ์์์ ์์ ์ฑ ํ์ธ
- ์ฌ๋ฌ API ํธ์ถ์ด ์ฐ์์ ์ผ๋ก ์ด๋ฃจ์ด์ง๋ ์๋๋ฆฌ์ค์ TPS/RPS ์ธก์
- ํน์ด์ฌํญ
- ํ๋์ ์ฝ์ํธ ์ค์ผ์ค์ ๋ํ ์ข์์ 5๋ง ๊ฐ๋ก ์ค์ ํ์ต๋๋ค. ์ด๋ ์ค์ ์ฝ์ํธ๊ฐ ๊ฒฝ๊ธฐ์ฅ์์ ์ด๋ฆด ๋๋ฅผ ๊ณ ๋ คํ์ฌ ์ค์ ํ์ต๋๋ค.
2. ํ ์คํธ ํ๊ฒฝ
AWS ๋ฑ ์ธ๋ถ ํด๋ผ์ฐ๋ ๋น์ฉ์ ์ ์ฝํ๊ธฐ ์ํด, ๋ก์ปฌ Docker ํ๊ฒฝ์์ ํ ์คํธ๋ฅผ ์งํํ์ต๋๋ค.
- ํ๊ฒฝ ๊ตฌ์ฑ
- Docker Compose๋ก ์คํ
- Spring Boot ์ ํ๋ฆฌ์ผ์ด์
- MySQL
- Kafka
- Redis
- ๋ฆฌ์์ค ์ ํ
- CPU: 0.5 vCPU ~ 2 vCPU
- ๋ฉ๋ชจ๋ฆฌ: 512M ~ 4G
- ํ ์คํธ ๋๊ตฌ
- k6
- ๋ถํ ํ ์คํธ ์คํฌ๋ฆฝํธ ์์ฑ ๋ฐ ์คํ
- ๋ชฉํ TPS ์ค์ ๊ณผ SLO ๊ฒ์ฆ
- Prometheus + InfluxDB + Grafana
- Spring Boot Actuator์ ์ฐ๋ํด ๋ฉํธ๋ฆญ ์์ง ๋ฐ ์๊ฐํ
- k6 ๊ฒฐ๊ณผ์ ํจ๊ป ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง
3. ๋ชฉํ์ ๊ฒ์ฆ ๊ธฐ์ค
- ์์คํ ํ๊ณ ์ธก์
ํ ์คํธ์ ์ฃผ์ ๋ชฉํ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์ต๋ TPS: ์์คํ ์ด ๋์์ ์ฒ๋ฆฌํ ์ ์๋ ์์ฒญ์ ์ต๋ ๊ฐ์
- ํ๊ท TPS: ์ง์์ ์ธ ๋ถํ ์ํฉ์์ ์ฒ๋ฆฌ ๊ฐ๋ฅํ ํ๊ท ์์ฒญ ๊ฐ์
- ํ๊ท RPS (Requests Per Second): ์ด๋น ์์ฒญ ์ฒ๋ฆฌ๋
- SLA / SLO ๊ธฐ์ค
์๋น์ค์ ํ์ง ๋ชฉํ๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํ์ต๋๋ค:
- SLO
- p99 ์๋ต ์๊ฐ: 400ms ์ดํ
- ์ฑ๊ณต๋ฅ : 99% ์ด์
- SLA
- ํ๊ท ์๋ต ์๊ฐ: 200ms ์ดํ
- ์ด๋น ์์ฒญ ์ฒ๋ฆฌ๋: ์ต์ 50 TPS
- ์ต๋ ๋ถํ ์กฐ๊ฑด์์ ์๋น์ค ์ค๋จ ๋ฐ์๋ฅ : 0%
4. ํ ์คํธ ์ค๊ณ์ ์คํฌ๋ฆฝํธ
- ํ ์คํธ ์ค๊ณ
๊ฐ ํ ์คํธ๋ ์๋๋ฆฌ์ค ๋ณ Docker ๋ฆฌ์์ค ์คํ(3๊ฐ)์ ํ ์คํธ ์ ๋ต(2๊ฐ)์ ์กฐํฉ์ผ๋ก ์ด 6๊ฐ๋ก ์ค์ ํ์ต๋๋ค.
1. Docker ์คํ
- 0.5vCPU, 512MB
- 1vCPU, 1GB
- 2vCPU, 2GB
2. ํ ์คํธ ์ ๋ต
- VU ์ฆ๊ฐ ํ ์คํธ - ์ ์ง์ ์ฆ๊ฐ๋ก ์ต๋ ์ฒ๋ฆฌ๋ ํ์ธ
export let options = {
stages: [
{ duration: '10s', target: 10 }, // 10์ด ๋์ 10 VU๋ก ์ฆ๊ฐ
{ duration: '10s', target: 30 }, // 10์ด ๋์ 30 VU๋ก ์ฆ๊ฐ
{ duration: '10s', target: 50 }, // 10์ด ๋์ 50 VU๋ก ์ฆ๊ฐ
{ duration: '10s', target: 100 }, // 10์ด ๋์ 100 VU๋ก ์ฆ๊ฐ
{ duration: '10s', target: 200 }, // 10์ด ๋์ 200 VU๋ก ์ฆ๊ฐ
{ duration: '10s', target: 0 }, // 10์ด ๋์ 0์ผ๋ก ๊ฐ์
],
thresholds: {
http_req_duration: ['p(99)<400'], // p99๊ฐ 400ms ์ดํ
http_req_failed: ['rate<0.01'], // ์คํจ์จ์ด 1% ์ดํ
},
};
- ์คํ์ดํฌ ํ ์คํธ - ๊ฐ์์ค๋ฌ์ด ๋ถํ ๋ณต์ ๋ฅ๋ ฅ ํ์ธ
export let options = {
stages: [
{ duration: '10s', target: 100 }, // 10์ด ๋์ 100 VU
{ duration: '10s', target: 1000 }, // 10์ด ๋์ 1000 VU๋ก ๊ธ์ฆ
{ duration: '30s', target: 100 }, // 30์ด ๋์ 100 VU๋ก ๊ฐ์
],
thresholds: {
http_req_duration: ['p(99)<400'], // p99 ์๋ต ์๊ฐ ์กฐ๊ฑด
http_req_failed: ['rate<0.05'], // ์คํจ์จ ์กฐ๊ฑด (์คํ์ดํฌ์์๋ 5% ํ์ฉ)
},
};
- ์๋๋ฆฌ์ค 1: ์ ์ ๋นํ์ฑ
์ ์ ํ ํฐ ๋ฐ๊ธ -> ํ ํฐ ์ํ ์กฐํ (1์ด ๊ฐ๊ฒฉ์ผ๋ก 5ํ ๋ฐ๋ณต)
export default function () {
// ํ ํฐ ๋ฐ๊ธ
let token = getWaitingToken()
// ํ ํฐ ์ํ ์กฐํ
for (let i = 0; i < 5; i++) { // 5ํ ๋ฐ๋ณต
getQueueStatus(token)
sleep(1);
}
}
1. 1vCPU, 512MB & VU ์ฆ๊ฐ ํ ์คํธ


2. 2vCPU, 1GB & VU ์ฆ๊ฐ ํ ์คํธ


3. 2vCPU, 2GB & VU ์ฆ๊ฐ ํ ์คํธ


5.1vCPU, 512MB & ์คํ์ดํฌ ํ ์คํธ


5. 2vCPU, 1GB & ์คํ์ดํฌ ํ ์คํธ




- ์๋๋ฆฌ์ค 2: ์ ์ ํ์ฑ
ํ์ฑ ํ ํฐ ๋ฐ๊ธ -> ์ข์ ์กฐํ -> ์ข์ ์์ฝ -> ๊ฒฐ์
export default function () {
let token = getActiveToken();
getConcertSeats(token);
sleep(2);
let reservationId = reserveSeat(token);
sleep(2);
processPayment(token, reservationId);
sleep(2);
}
2024-11-29 00:22:12 2024-11-28T15:22:11.293Z ERROR 1 --- [concert-reservation] [io-8080-exec-32] h.c.i.api.GlobalExceptionHandler : Exception: [INTERNAL_SERVER_ERROR] CannotCreateTransactionException - An unexpected error occurred..
2024-11-29 00:22:12
2024-11-29 00:22:12 org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction
2024-11-29 00:22:12 at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:466) ~[spring-orm-6.1.13.jar!/:6.1.13]
...
2024-11-29 00:22:13 Caused by: java.lang.OutOfMemoryError: Java heap space
...
2024-11-29 00:22:13 2024-11-28T15:22:11.296Z ERROR 1 --- [concert-reservation] [io-8080-exec-47] h.c.i.api.GlobalExceptionHandler : Exception: [INTERNAL_SERVER_ERROR] CannotCreateTransactionException - An unexpected error occurred..
2024-11-29 00:22:13
2024-11-29 00:22:13 org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction
...
2024-11-29 00:22:13 Caused by: org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection [HikariPool-1 - Connection is not available, request timed out after 20436ms (total=23, active=23, idle=0, waiting=24)] [n/a]
...
2024-11-29 00:23:34 org.springframework.orm.jpa.JpaSystemException: JDBC exception executing SQL [/* <criteria> */ select s1_0.`id`,s1_0.`created_at`,s1_0.`price`,s1_0.`schedule_id`,s1_0.`seat_number`,s1_0.`status`,s1_0.`updated_at`,s1_0.`version` from `seat` s1_0 where s1_0.`schedule_id`=?] [Java heap space] [n/a]
export let options = {
stages: [
{ duration: '10s', target: 10 }, // 10์ด ๋์ 10 VU๋ก ์ฆ๊ฐ
{ duration: '10s', target: 15 }, // 10์ด ๋์ 20 VU๋ก ์ฆ๊ฐ
{ duration: '10s', target: 20 }, // 10์ด ๋์ 30 VU๋ก ์ฆ๊ฐ
{ duration: '10s', target: 25 }, // 10์ด ๋์ 50 VU๋ก ์ฆ๊ฐ
{ duration: '10s', target: 30 }, // 10์ด ๋์ 50 VU๋ก ์ฆ๊ฐ
{ duration: '10s', target: 0 }, // 10์ด ๋์ 0์ผ๋ก ๊ฐ์
],
thresholds: {
http_req_duration: ['p(99)<400'], // p99๊ฐ 400ms ์ดํ
http_req_failed: ['rate<0.01'], // ์คํจ์จ์ด 1% ์ดํ
},
};


5. ํ ์คํธ ๊ฒฐ๊ณผ์ ๋ถ์
- Docker ๋ฆฌ์์ค ์กฐ์ ๊ณผ ํ ์คํธ ์ ๋ต์ ๋ฐ๋ฅธ ์ฑ๋ฅ
Docker ์คํ | ํ ์คํธ ์ ๋ต | p95 ์๋ต ์๊ฐ(ms) | ์ต๋ RPS | ์ฑ๊ณต๋ฅ (%) |
1vCPU, 512MB | VU ์ฆ๊ฐ ํ ์คํธ | 13.1 | 239 | 100% |
1vCPU, 512MB | ์คํ์ดํฌ ํ ์คํธ | 3830 | 555 | 100% |
2vCPU, 1GB | VU ์ฆ๊ฐ ํ ์คํธ | 5.26 | 239 | 100% |
2vCPU, 1GB | ์คํ์ดํฌ ํ ์คํธ | 1150 | 950 | 100% |
2vCPU, 2GB | VU ์ฆ๊ฐ ํ ์คํธ | 6.69 | 240 | 100% |
2vCPU, 2GB | ์คํ์ดํฌ ํ ์คํธ | 1420 | 948 | 100% |
- ๋ถ์
1. 1vCPU, 512MB ๋ฆฌ์์ค ํ๊ฒฝ
- VU ์ฆ๊ฐ ํ
์คํธ
- p95 ์๋ต ์๊ฐ์ 13.1ms๋ก ๋งค์ฐ ์ฐ์ํ๋ฉฐ, SLO ๊ธฐ์ค(p99 < 400ms) ์ถฉ์กฑ
- ์ต๋ RPS 239๋ก ๋์ ์์ฒญ ์ฒ๋ฆฌ๋์ ์ ํ์
- ์ ํ๋ ๋ฆฌ์์ค ๋ด์์๋ CPU์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ์์ ์
- ์คํ์ดํฌ ํ
์คํธ:
- p95 ์๋ต ์๊ฐ์ด 3830ms๋ก SLO ๊ธฐ์ค ๋ฏธ๋ฌ
- ์๊ฐ ๋ถํ์์ CPU์ ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ์ผ๋ก ์ธํด ์ฒ๋ฆฌ ์๋ ์ ํ ๋ฐ ๋ณ๋ชฉ ๋ฐ์
2. 2vCPU, 1GB ๋ฆฌ์์ค ํ๊ฒฝ
- VU ์ฆ๊ฐ ํ
์คํธ
- p95 ์๋ต ์๊ฐ์ด 5.26ms๋ก ๋งค์ฐ ์ฐ์ํ๋ฉฐ, ๋ชจ๋ SLO/SLA ๊ธฐ์ค ์ถฉ์กฑ
- ์ต๋ RPS 239๋ก ๋์ ์์ฒญ ์ฒ๋ฆฌ๋์ ์ ํ๋ ํ๊ฒฝ๊ณผ ๋์ผํ์ง๋ง, CPU์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ์ฌ์ ๋ก์
- ์คํ์ดํฌ ํ
์คํธ
- p95 ์๋ต ์๊ฐ์ด 1150ms๋ก SLO ๊ธฐ์ค ๋ฏธ๋ฌ
- ์ต๋ RPS 950์ผ๋ก ์คํ์ดํฌ ๋ถํ๋ฅผ ์ฒ๋ฆฌํ ์ ์์ผ๋, ์ฐ๊ฒฐ ๋ณ๋ชฉ์ด ๋ฐ์
- ๋์ ์์ฒญ ์ฒ๋ฆฌ๋ ์ฆ๊ฐ ์ I/O ๋ณ๋ชฉ์ผ๋ก ์ธํด ์๋ต ์๋๊ฐ ๋๋ ค์ง
3. 2vCPU, 2GB ๋ฆฌ์์ค ํ๊ฒฝ
- VU ์ฆ๊ฐ ํ
์คํธ
- p95 ์๋ต ์๊ฐ์ด 6.69ms๋ก ๋งค์ฐ ์ฐ์ํ๋ฉฐ, ๋ชจ๋ SLO/SLA ๊ธฐ์ค ์ถฉ์กฑ
- ์ต๋ RPS 240์ผ๋ก ๋์ ์์ฒญ ์ฒ๋ฆฌ๋์ด ์์ ์
- ๋ถํ ๋ถ์ฐ์ด ์ ์ด๋ฃจ์ด์ก์ผ๋ฉฐ, ๋ณ๋ชฉ ์์ด ์ฒ๋ฆฌ ๊ฐ๋ฅ
- ์คํ์ดํฌ ํ
์คํธ
- p95 ์๋ต ์๊ฐ์ด 1420ms๋ก SLO ๊ธฐ์ค ๋ฏธ๋ฌ
- ์ต๋ RPS 948๋ก ๋์ ํธ๋ํฝ์ ์ฒ๋ฆฌํ ์ ์์ผ๋, ์๊ฐ์ ์ธ ์์ฒญ ํญ์ฃผ์์ ์ง์ฐ ๋ฐ์
- I/O ์ฒ๋ฆฌ ๋ณ๋ชฉ์ผ๋ก ์ธํ ์ง์ฐ ๊ฐ๋ฅ์ฑ
4. ์๋๋ฆฌ์ค 2 ๋ฏธํด๊ฒฐ ๋ฌธ์
- ๋์ ์คํ์ดํฌ ํธ๋ํฝ์ ์ฒ๋ฆฌํ๋ ๋ฐ ์์ด ๋ชจ๋ ํ๊ฒฝ์์ Redis๋ DB ์ฐ๊ฒฐ ๋ณ๋ชฉ์ด ๋ฐ์ ๊ฐ๋ฅ
- Redis ์ปค๋ฅ์ ํ ๋ถ์กฑ ๋๋ DB์ ํธ๋์ญ์ ์ฒ๋ฆฌ ํ๊ณ๊ฐ ๋ณ๋ชฉ์ ์ฃผ์ ์์ธ์ผ ๊ฐ๋ฅ์ฑ์ด ๋์
- ์ ํ๋ CPU/๋ฉ๋ชจ๋ฆฌ์์ ์คํ์ดํฌ ํธ๋ํฝ ์ ๋ณ๋ชฉ ํ์์ด ์ฌํ๋จ
6. ๊ฒฐ๋ก
- ์์คํ
ํ๊ณ ์ธก์
- ์ ํ๋ ๋ฆฌ์์ค ํ๊ฒฝ์์๋ CPU์ ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ์ด ์ฑ๋ฅ ๋ณ๋ชฉ์ ์ฃผ์ ์์ธ
- DB ์ปค๋ฅ์ ํ ํฌ๊ธฐ ์ฆ๊ฐ ๋ฐ ์ฟผ๋ฆฌ ์ต์ ํ ํ์
- SLA/SLO ๊ฒ์ฆ
- 2vCPU, 2GB ํ๊ฒฝ์์ ์ต๋ TPS 948๊ณผ ํ๊ท ์๋ต ์๊ฐ 200ms ์ดํ๋ก SLO ๊ธฐ์ค ์ถฉ์กฑ
- VU ์ฆ๊ฐ ํ ์คํธ์์๋ SLO ๊ธฐ์ค์ ๋ชจ๋ ์ถฉ์กฑํ์ผ๋, ์คํ์ดํฌ ๋ถํ์์๋ ๋ชจ๋ ์ฑ๋ฅ ๋ณ๋ชฉ์ด ๋ฐ์
- ํฅํ ๊ณํ
- AWS ํ๊ฒฝ์์ ์ค์ ๋ฐฐํฌ๋ฅผ ์๋ฎฌ๋ ์ด์ ํ์ฌ ๋ ๋์ ํธ๋ํฝ ์ฒ๋ฆฌ ์ฑ๋ฅ์ ๊ฒ์ฆ
- ์บ์ฑ, ๋น๋๊ธฐ ์ฒ๋ฆฌ, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ต์ ํ ๋ฑ์ผ๋ก ์ฑ๋ฅ์ ์ถ๊ฐ ๊ฐ์
๋ง์น๋ฉฐ
์ด๋ฒ ํ ์คํธ๋ฅผ ํตํด Docker ํ๊ฒฝ์์ ์์ ์กฐ์ ๊ณผ ๋ถํ ํ ์คํธ ์กฐํฉ์ผ๋ก ์์คํ ์ ์์ ์ฑ๊ณผ ์ฑ๋ฅ ํ๊ณ๋ฅผ ํ์ธํ ์ ์์์ต๋๋ค. ์ค์ ์ด์ ํ๊ฒฝ์์๋ ์ฑ๋ฅ์ ๊ฐ์ ํ๊ธฐ ์ํด ์ด๋ค ์ ์ ๊ณ ๋ คํด์ผ ํ ์ง ์๊ฐํด ๋ณผ ์ ์๋ ์๊ฐ์ด์์ต๋๋ค.