홈 › 실무 확장 › 22 / 22

성능 측정: p50·p95·p99, 측정 계층, JFR, JMH 함정, 자체 부하 테스트, 병목 순위

섹션 7진행 0 / 22

6. 연습 문제

문제 1. `Bench` 에 최솟값·최댓값 출력 추가

Bench.measure 가 p50·p95·p99·평균 외에 최솟값(min)과 최댓값(max)도 함께 출력하도록 수정하세요. 힌트: 정렬된 samples 배열의 첫 번째와 마지막 원소를 사용합니다.

java
double min = samples[0] / 1000.0;
double max = samples[samples.length - 1] / 1000.0;
System.out.printf(" min=%7.1fus max=%7.1fus", min, max);

정렬을 이미 했으므로 별도 순회 없이 배열 양 끝만 읽으면 됩니다.

문제 2. 부하 테스트에 램프업 추가

demo4LoadTest 가 요청을 한 번에 모두 제출하는 대신, 0.5초에 걸쳐 서서히 제출하도록 바꾸세요. 힌트: 요청 사이에 Thread.sleep을 짧게 넣거나, 제출 시작 시각을 요청 순번에 비례해 지연시킵니다.

java
long delayMs = (i * 500L) / total; // 0~500ms 사이로 분산 제출
pool.submit(() -> {
    try {
        Thread.sleep(delayMs);
    } catch (InterruptedException ignored) {
        Thread.currentThread().interrupt();
    }
    // 이후 기존 요청 로직
});

램프업을 넣으면 초반 커넥션 생성 지연이 결과에 덜 섞여, 안정 구간에 가까운 p95 를 얻습니다.

문제 3. N+1 쿼리 시나리오를 텍스트로 설명하기

주문 목록 20건을 조회한 뒤 각 주문의 상품명을 각각 SELECT 로 가져오는 코드가 있다고 가정합니다. 이 코드가 왜 느린지, 그리고 어떤 측정 방법으로 이 문제를 발견할 수 있는지 설명하세요.

주문 20건이면 목록 조회 1회에 상품명 조회 20회가 추가되어 총 21회의 쿼리가 나갑니다. 요청마다 DB 왕복이 20번 늘어, 각 왕복이 5ms 만 걸려도 100ms 가 추가됩니다.

MyBatis 로그나 p6spy 로 같은 요청 안에서 비슷한 SQL 이 반복 실행되는 것을 보면 발견할 수 있습니다. 해결은 fetch join 이나 `IN` 절 일괄 조회로 쿼리 수를 1~2회로 줄이는 것입니다.