[System Design Lab] 0. 반복 가능한 System Design Template 만들기

2 분 소요

Repository : [Github] System-Design-Template

왜 템플릿부터 만들었을까

Backend System Design Lab의 첫 프로젝트로 URL Shortener를 바로 구현하지 않고, 먼저 모든 프로젝트에서 공통으로 사용할 System Design Template을 만들었다.

앞으로 다룰 시스템은 서로 다르지만 실험 과정은 대부분 비슷하다.

요구사항 정의
→ 기본 구조 구현
→ 부하 테스트
→ 병목 분석
→ 구조 개선
→ 동일한 조건으로 재측정

프로젝트마다 Spring Boot, Docker, Prometheus, Grafana, k6 환경을 다시 구성하면 반복 작업이 많아진다. 무엇보다 실행 환경과 측정 방식이 달라지면 프로젝트별 결과를 같은 기준으로 비교하기 어렵다.

그래서 본격적인 구현에 앞서 다음 목표를 가진 공통 환경부터 만들었다.

새로운 프로젝트를 빠르게 시작하고, 같은 방법으로 실행하며, 같은 기준으로 측정할 수 있는 환경을 만든다.


템플릿에 포함한 것

전체 구조는 다음과 같다.

k6
 ↓ HTTP 부하
Spring Boot
 ↓ Actuator / Micrometer
Prometheus
 ↓
Grafana

각 도구의 역할은 단순하게 나눴다.

구성 요소 역할
Spring Boot 시스템 API 구현
Docker Compose 동일한 실행 환경 제공
k6 Smoke·Load·Stress Test
Prometheus 애플리케이션 메트릭 수집
Grafana 응답 시간과 자원 사용량 시각화
GitHub Actions 빌드·테스트·실행 자동 검증

현재 템플릿에는 MySQL, Redis, Kafka를 기본으로 넣지 않았다.

모든 기술을 미리 추가하기보다 각 프로젝트에서 실제 병목과 요구사항이 확인됐을 때 필요한 기술만 도입하기 위해서다.


측정할 수 있는 환경 만들기

성능 개선에서 중요한 것은 단순히 응답 시간이 빨라졌다는 결과가 아니라, 왜 빨라졌는지 설명할 수 있는 것이라고 생각한다.

그래서 Grafana Dashboard에서 다음 지표를 기본적으로 확인할 수 있도록 구성했다.

Requests Per Second
p95·p99 응답 시간
5xx 오류율
JVM Heap
CPU 사용률

k6 테스트도 목적에 따라 세 가지로 나눴다.

  • Smoke Test: 서비스가 기본적으로 동작하는지 확인
  • Load Test: 예상 부하에서 성능 기준을 만족하는지 확인
  • Stress Test: 시스템이 한계에 도달하는 구간 탐색

GitHub Actions에서는 실행 시간이 짧고 안정적인 Smoke Test까지만 수행하고, Load Test와 Stress Test는 직접 메트릭을 관찰하면서 실행하도록 했다.


Platform Thread와 Virtual Thread 비교 준비

이번 Lab에서는 이후 프로젝트에서 Platform Thread와 Virtual Thread의 차이도 비교할 예정이다.

Spring Boot 설정은 환경변수 하나로 변경할 수 있도록 구성했다.

VIRTUAL_THREADS_ENABLED=false

다만 현재 템플릿의 Ping API에는 DB나 외부 API 호출이 없기 때문에 지금 비교하는 것은 의미가 없다.

추후 블로킹 I/O가 포함된 프로젝트에서 같은 k6 시나리오를 사용해 RPS, p95, p99, CPU, 스레드 수와 DB Connection Pool 대기 시간을 비교할 계획이다.

가상 스레드를 무조건 좋은 기술로 가정하기보다, 어떤 조건에서 효과가 나타나는지 직접 확인하는 것이 목적이다.


설계 과정도 템플릿으로 관리하기

코드뿐 아니라 설계 과정도 같은 형식으로 남기기 위해 다음 문서를 준비했다.

docs/
├── 01-requirements.md
├── 02-capacity-estimation.md
├── 03-architecture.md
├── 04-experiment.md
└── 05-retrospective.md

요구사항과 용량을 먼저 정의하고, 초기 설계와 실험 가설을 기록한 뒤 개선 결과와 트레이드오프까지 남기는 구조다.

구현이 끝난 후 결과만 정리하는 것이 아니라, 처음에 어떤 가정을 했고 실제 결과는 어떻게 달랐는지를 확인하기 위해 만들었다.


이번 단계에서 얻은 것

이번 작업에서 가장 크게 느낀 점은 성능 실험을 시작하기 전에 먼저 반복 가능한 조건을 만들어야 한다는 것이다.

같은 실행 환경
같은 부하 조건
같은 측정 지표

이 조건이 유지되어야 구조 변경이 실제로 어떤 영향을 주었는지 설명할 수 있다.

또한 재사용 가능한 템플릿은 단순히 파일이 잘 복사되는 것으로 끝나지 않는다.

새로운 Repository에서도 별도의 수작업 없이 빌드, 실행, 측정까지 이어져야 한다.


이제부터는 환경을 다시 구성하는 데 시간을 쓰기보다 각 시스템의 요구사항과 병목에 집중할 수 있게 됐다.

다음 단계에서는 이 템플릿을 기반으로 첫 번째 프로젝트인 URL Shortener의 요구사항과 예상 트래픽을 정의한다.

1. URL Shortener 요구사항 정의와 용량 산정

카테고리:

업데이트: