아래는 **6장. 성능 및 부하 테스트**에 대한 글입니다. 이 장은 스프링 부트 애플리케이션의 성능과 부하를 테스트하는 방법을 다루며, 실무에서 자주 사용하는 도구와 분석 방법을 소개합니다. 실습 예제를 포함해 실질적인 이해를 돕고자 했습니다.

---

## 6장. 성능 및 부하 테스트

애플리케이션의 기능이 올바르게 동작하는지를 확인하는 단위 및 통합 테스트를 넘어, 실제 사용자 트래픽을 감당할 수 있는지 확인하는 성능 및 부하 테스트는 필수적입니다. 스프링 부트 애플리케이션의 성능 병목 지점을 찾고, 확장성을 검증하는 방법을 이 장에서 다룹니다. JMeter와 Gatling을 활용한 실습과 결과 분석까지 포함했습니다.

### 6.1 스프링 부트 애플리케이션 성능 테스트 개요

성능 테스트는 애플리케이션이 특정 조건에서 얼마나 잘 동작하는지 측정합니다. 부하 테스트는 그 하위 범주로, 높은 트래픽이나 동시 사용자 요청을 시뮬레이션해 시스템의 한계를 확인합니다. 주요 목표는 다음과 같습니다:
- **응답 시간**: 요청 처리 속도가 적절한지.
- **처리량(Throughput)**: 초당 처리할 수 있는 요청 수.
- **안정성**: 부하 증가 시 시스템이崩溃하지 않는지.

스프링 부트는 내장 톰캣 서버와 자동 설정으로 빠르게 실행되지만, 데이터베이스 연결, 캐싱, 비동기 처리 등에서 병목이 발생할 수 있습니다. 이를 테스트로 사전에 파악해야 합니다.

### 6.2 JMeter를 활용한 부하 테스트

Apache JMeter는 오픈소스 부하 테스트 도구로, HTTP 요청을 시뮬레이션하고 결과를 분석하는 데 유용합니다. 설치 후 간단한 테스트를 설정해 봅시다.

#### JMeter 설정
1. [JMeter 공식 사이트](https://jmeter.apache.org/)에서 다운로드 후 실행.
2. 테스트 계획(Test Plan) 생성:
   - **스레드 그룹(Thread Group)**: 동시 사용자 수(예: 100명), 반복 횟수 설정.
   - **HTTP 요청(HTTP Request)**: 대상 URL(예: `http://localhost:8080/users/1/name`) 입력.
   - **리스너(Listener)**: 결과 트리(View Results Tree), 요약 리포트(Summary Report) 추가.

#### 예제 테스트
`UserController`의 `/users/1/name` 엔드포인트를 테스트한다고 가정:
- 스레드 수: 100
- 반복 횟수: 10
- 요청: GET `/users/1/name`

JMeter에서 테스트 실행 후 결과:
- **평균 응답 시간**: 50ms
- **처리량**: 200 req/s
- **에러율**: 0%

#### 분석
응답 시간이 길거나 에러가 발생하면 데이터베이스 쿼리 최적화, 캐싱 추가 등 개선이 필요합니다. JMeter는 CSV로 결과를 내보내 상세 분석도 가능합니다.

### 6.3 Gatling으로 시나리오 기반 테스트

Gatling은 스칼라 기반의 고성능 부하 테스트 도구로, 시나리오를 코드로 작성해 복잡한 사용자 행동을 시뮬레이션할 수 있습니다. JMeter보다 가볍고, HTML 리포트가 직관적입니다.

#### Gatling 설정
의존성 추가 (Maven 프로젝트로 설정):

```xml
<dependency>
    <groupId>io.gatling.highcharts</groupId>
    <artifactId>gatling-charts-highcharts</artifactId>
    <version>3.9.5</version>
    <scope>test</scope>
</dependency>
```

#### 테스트 시나리오 작성
`src/test/scala`에 시나리오 작성:

```scala
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._

class UserApiSimulation extends Simulation {
  val httpProtocol = http
    .baseUrl("http://localhost:8080")
    .acceptHeader("application/json")

  val scn = scenario("User API Load Test")
    .exec(http("Get User Name")
      .get("/users/1/name"))
    .pause(1) // 1초 대기

  setUp(
    scn.inject(
      rampUsers(100).during(10.seconds) // 10초 동안 100명 증가
    )
  ).protocols(httpProtocol)
}
```

#### 실행 및 결과
`mvn gatling:test`로 실행하면 HTML 리포트가 `target/gatling`에 생성됩니다. 리포트는 응답 시간 분포, 요청별 통계 등을 시각화합니다.

### 6.4 성능 테스트 결과 분석

성능 테스트 결과를 분석하려면 다음 지표를 확인합니다:
- **응답 시간 분포**: 90번째 백분위수(90% 요청이 이 시간 내 처리됨)가 중요한 기준.
- **에러율**: 1% 이상이면 문제 원인을 조사.
- **리소스 사용량**: CPU, 메모리, 디스크 I/O를 모니터링(예: `top`, Prometheus).

#### 예제 분석
JMeter 결과:
- 평균 응답 시간: 50ms
- 90% 응답 시간: 70ms
- 처리량: 200 req/s

Gatling 결과:
- 최대 응답 시간: 120ms
- 실패 요청: 0건

응답 시간이 100ms를 넘거나 실패가 발생하면 다음 조치를 고려합니다:
- **쿼리 최적화**: 인덱스 추가, 불필요한 조인 제거.
- **캐싱**: Redis나 Spring Cache 도입.
- **스케일링**: 서버 인스턴스 추가.

#### 모니터링 도구 연동
Spring Boot Actuator를 활성화해 성능 지표를 수집할 수 있습니다:

```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
```

`application.properties`:
```properties
management.endpoints.web.exposure.include=health,metrics
```

`/actuator/metrics` 엔드포인트로 HTTP 요청 수, 응답 시간 등을 확인하며 테스트와 연계합니다.

---

### 마무리

성능 및 부하 테스트는 스프링 부트 애플리케이션이 실전에서 안정적으로 동작할 수 있는지 확인하는 마지막 관문입니다. JMeter로 간단한 부하를 시뮬레이션하고, Gatling으로 복잡한 시나리오를 테스트하며, 결과를 분석해 병목을 개선할 수 있습니다. 다음 장에서는 CI/CD 파이프라인에 테스트를 통합해 개발 프로세스를 자동화하는 방법을 다루겠습니다. 성능 테스트로 여러분의 애플리케이션을 한 단계 업그레이드해 보세요!

---

이 글은 성능 테스트의 핵심 개념과 도구 사용법을 다루며, 실습과 분석을 통해 실무 적용 가능성을 높였습니다. 추가 요청이나 수정 사항이 있다면 말씀해 주세요!