# 폴리글롯 마이크로서비스 게임 로드테스트 결과와 k6 활용법: 초보자를 위한 사례 연구 및 실전 적용 팁

---

# # 서론 – 왜 로드테스트가 필요할까?

멀티플레이어 게임을 **폴리글롯**(다중 언어) 마이크로서비스 구조로 개발하면 각각의 서비스가 독립적으로 배포·확장될 수 있어 큰 장점이 있습니다. 하지만 실제 서비스가 시작되면 **동시 접속자 수**가 급증하면서 응답 지연, 서버 오류 등 다양한 문제가 발생할 수 있습니다.

> **문제 제기**

> * “내가 만든 게임은 10명 정도는 문제 없이 동작한다.”

> * “하지만 100명, 1,000명 규모가 되면 서버가 다운된다.”

이러한 상황을 미리 예측하고 대비하려면 **로드테스트**가 필수입니다. 이번 포스트에서는 오픈소스 로드테스트 도구 **k6**를 활용해 우리 폴리글롯 마이크로서비스 게임을 시험한 과정을 단계별로 소개합니다. 초보자도 따라 할 수 있도록 쉬운 설명을 제공하니, 곧바로 실전 적용해 보세요!

---

# # 1. 폴리글롯 마이크로서비스 아키텍처 살펴보기

| 서비스 | 언어 | 역할 |

|--------|------|------|

| **Auth** | Go | 사용자 인증·JWT 발급 |

| **Lobby** | Node.js | 방 생성·매칭 로직 |

| **Game** | Python (FastAPI) | 게임 진행·점수 계산 |

| **Chat** | Rust | 실시간 채팅 전송 |

| **Metrics** | Java | Prometheus 연동·모니터링 |

각 서비스는 Docker 컨테이너로 독립 실행되며, **API Gateway**(NGINX) 를 통해 외부 요청을 라우팅합니다. 이런 구조는 확장성은 높지만, **네트워크 지연**이나 **서비스 간 의존성** 문제가 쉽게 발생합니다. 따라서 로드테스트 시 **전체 흐름**(인증 → 로비 → 게임 → 채팅)을 모두 포함해야 정확한 결과를 얻을 수 있습니다.

---

# # 2. k6 로드테스트 준비 과정

## # 2.1 k6 설치 및 기본 사용법

```
bash

# macOS

brew install k6

# Linux (Debian/Ubuntu)

sudo apt-get install -y k6

```

설치가 끝났다면 가장 간단한 스크립트부터 실행해 보세요.

```
javascript

import http from 'k6/http';

import { sleep } from 'k6';

export const options = {

  vus: 10,          // 가상 사용자의 수

  duration: '30s', // 테스트 지속 시간

};

export default function () {

  http.get('http://localhost:8080/health');

  sleep(1);

}

```

`k6 run script.js` 명령으로 실행하면, 10명의 가상 사용자가 30초 동안 `/health` 엔드포인트에 요청을 보냅니다.

## # 2.2 실제 게임 시나리오 스크립트 만들기

우리 게임은 다음 흐름을 가정합니다.

1. **로그인** → `/auth/login` (POST)

2. **방 만들기** → `/lobby/create` (POST)

3. **게임 시작** → `/game/start` (POST)

4. **채팅 전송** → `/chat/send` (POST)

각 단계마다 토큰, 방 ID 등 동적으로 값을 받아야 합니다. k6는 JavaScript를 사용하므로 변수와 함수로 손쉽게 구현할 수 있습니다.

```
javascript

import http from 'k6/http';

import { check, sleep } from 'k6';

import { uuidv4 } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js';

export const options = {

  stages: [

    { duration: '1m', target: 50 },   // 워밍업

    { duration: '3m', target: 200 },  // 피크

    { duration: '1m', target: 0 },    // 다운

  ],

};

export default function () {

  // 1️⃣ 로그인

  const loginRes = http.post('http://localhost:8080/auth/login', {

    username: `user_${__VU}`,

    password: 'test123',

  });

  check(loginRes, { 'login succeeded': (r) => r.status === 200 });

  const token = loginRes.json('token');

  // 2️⃣ 방 만들기

  const lobbyRes = http.post(

    'http://localhost:8080/lobby/create',

    { roomId: uuidv4() },

    { headers: { Authorization: `Bearer ${token}` } }

  );

  check(lobbyRes, { 'room created': (r) => r.status === 201 });

  const roomId = lobbyRes.json('roomId');

  // 3️⃣ 게임 시작

  const gameRes = http.post(

    `http://localhost:8080/game/start`,

    { roomId },

    { headers: { Authorization: `Bearer ${token}` } }

  );

  check(gameRes, { 'game started': (r) => r.status === 200 });

  // 4️⃣ 채팅 전송

  http.post(

    `http://localhost:8080/chat/send`,

    { roomId, message: 'Hello from k6!' },

    { headers: { Authorization: `Bearer ${token}` } }

  );

  sleep(1);

}

```

위 스크립트는 **동시 사용자 수**를 단계적으로 늘리면서 실제 게임 흐름을 재현합니다. `check` 함수를 통해 각 응답이 정상인지 검증하고, 결과는 k6가 자동으로 요약해 줍니다.

## # 2.3 결과 저장 및 시각화

```
bash

k6 run --out json=report.json script.js

```

생성된 `report.json` 파일을 **Grafana**와 연동하거나, k6 Cloud(무료 플랜)로 업로드하면 대시보드 형태로 **RPS**, **응답 시간**, **오류 비율** 등을 한눈에 파악할 수 있습니다.

---

# # 3. 테스트 결과 분석

| 단계 | 목표 VU | 평균 응답시간 (ms) | 95th Percentile (ms) | 오류율 |

|------|--------|-------------------|----------------------|--------|

| 워밍업 (1분) | 50 | 85 | 120 | 0% |

| 피크 (3분)   | 200 | 210 | 350 | 1.3% |

| 다운 (1분)   | 0   | -   | -    | -   |

## # 3.1 병목 현상 발견

* **Auth 서비스**(Go) – 평균 120 ms, 95th Percentile 250 ms 로 가장 지연이 컸습니다. 로그를 확인한 결과 **JWT 서명**에 사용된 RSA 키가 2048비트라 CPU 부하가 높았습니다.

* **Chat 서비스**(Rust) – 오류율 0.8%는 WebSocket 연결 타임아웃 때문이었음. 연결 수가 급증하면서 **keep‑alive** 설정이 부족했습니다.

## # 3.2 리소스 사용량

k6 실행 시 **Docker stats**를 함께 모니터링했더니, Game 서비스(Python) 컨테이너가 메모리 1.2 GB까지 급증했습니다. 이는 **점수 계산 로직**이 비동기 처리되지 않아 발생한 문제였습니다.

---

# # 4. 배운 점과 개선 방안

1. **k6 스크립트 재사용성**

   - 공통 함수(`login()`, `createRoom()`)를 모듈화하면 다른 테스트에 쉽게 적용 가능.

2. **Auth 서비스 최적화**

   - RSA 대신 **ECDSA**(256비트) 알고리즘으로 교체 → CPU 사용량 30% 절감.

3. **Chat 서비스 설정**

   - NGINX에서 `proxy_read_timeout`을 60초로 늘리고, **WebSocket keep‑alive** 옵션을 활성화.

4. **Game 서비스 비동기화**

   - 점수 계산을 **Celery** 워커로 분리 → 메모리 사용량 45% 감소, 응답 시간 150 ms 개선.

5. **CI/CD 파이프라인에 로드테스트 자동화**

   - GitHub Actions에서 `k6 run` 명령을 실행하고, 실패 기준(예: 95th Percentile > 500 ms) 초과 시 배포 차단.

---

# # 결론 – 이제 직접 로드테스트를 시작해 보세요!

이번 **폴리글롯 마이크로서비스 게임** 사례를 통해 **k6**를 이용한 로드테스트 전 과정을 살펴보았습니다.

* **마이크로서비스 로드테스트**는 단순히 트래픽을 부여하는 것이 아니라, 서비스 간 의존성까지 검증하는 것이 핵심입니다.

* **k6 사용법**을 익히면 복잡한 시나리오도 간단한 JavaScript 코드로 구현할 수 있습니다.

* 테스트 결과를 바탕으로 **성능 개선**을 진행하면, 실제 서비스 운영 시 안정성을 크게 높일 수 있습니다.

> **행동 유도**

> 1. 오늘 소개한 스크립트를 복사해 로컬 환경에 바로 실행해 보세요.

> 2. 자신의 서비스에 맞게 엔드포인트와 파라미터를 수정하고, `stages`를 조정해 피크 트래픽을 시뮬레이션합니다.

> 3. 결과를 Grafana 대시보드에 연결해 실시간 모니터링을 시작하세요.

성공적인 로드테스트와 서비스 안정화, 여러분도 충분히 이룰 수 있습니다. 궁금한 점이나 추가적인 사례가 필요하면 댓글로 알려 주세요! 🚀

---

**SEO 키워드**: 마이크로서비스 로드테스트, k6 사용법, 폴리글롯 게임
