Skip to content

Performance

TAEHEON KIM edited this page Jun 26, 2026 · 3 revisions

Performance

부하테스트 환경

  • 도구: k6
  • 서버: AWS EC2 t3.large (2 vCPU / 8GB), 단일 인스턴스에 7개 서비스 공유

최적화 결과

1. HikariCP 커넥션 풀 튜닝

1만 명 동시 요청 시 기본 풀 10개로는 커넥션 고갈 -> 대기 누적 발생

Before After
커넥션 풀 기본값 10개 50개
p(95) 응답시간 9.76s 7.1s (27% 개선)

2. 비동기 알림 처리 (@Async)

댓글 저장 + 알림 DB 저장 + Redis 발행이 동기 처리되어 커넥션 풀 즉시 고갈

Before After
에러율 87% 2.3% (96% 감소)
RPS 137/s 940/s (585% 향상)

@Async("notificationExecutor")로 알림 처리를 별도 Virtual Thread 풀로 분리. ThreadPoolExecutor.DiscardPolicy로 풀 포화 시 알림만 조용히 버림 (API 정상 응답 유지)


3. Redis 캐싱 (게시글 단건 조회)

@Cacheable로 첫 조회 시 Redis 저장, 이후 DB 미조회. TTL 10분. RedisCacheErrorHandler로 Redis 장애 시 예외 전파 없이 DB 폴백 처리

Before (DB 직접 조회) After (Redis 캐시)
에러율 1.07% 0.52%
p(95) 5.38s 97.6ms (98% 개선)
RPS 1,825/s 3,686/s (2배 향상)
평균 응답시간 - 24.66ms

4. 비관적 락 (동시 지원 동시성 제어)

SELECT -> INSERT 사이 레이스컨디션으로 유니크 제약 위반 시 500 에러 발생

Before After
20건 동시 지원 성공률 5% (레이스컨디션) 100% (201 or 409)

PESSIMISTIC_WRITE 락 + DataIntegrityViolationException catch로 해결. 락 획득 타임아웃 3초 설정으로 데드락 시 무한 대기 방지. 락 획득 순서를 항상 게시글 -> 지원 단방향으로 고정해 순환 대기 제거


5. DB 인덱스 최적화

테이블 인덱스 목적
study_posts (status, deadline) 모집 중 게시글 필터링 + 마감임박순 정렬
study_posts (author_id, created_at) 내 게시글 조회
applies (post_id, status, created_at) 게시글별 지원 목록
notifications (receiver_id, is_read, created_at) 알림 목록 + 미읽음 필터
comments (post_id, created_at) 댓글 목록

p(95): 7.29s -> 6.5s 개선


6. Kafka DLQ + 지수 백오프

Consumer 처리 실패 시 재시도 3회 (1초 -> 2초 -> 4초 지수 백오프) 후 DLT 격리. 정상 처리 흐름을 막지 않고 실패 메시지를 별도 보관 후 수동 재처리

항목 내용
재시도 횟수 3회
DLT 토픽 post-sync.DLT, notification.DLT

7. EC2 배포 서버 성능

목록 조회 vs 단건 조회 (10,000 VUs)

지표 목록 조회 (MySQL) 단건 조회 (Redis)
에러율 71.45% 23.25%
RPS 408/s 555/s
성공률 28% 76%

안정 구간 (500 VUs, 총 50,000건)

지표 결과
에러율 0.01%
p(95) 277ms
성공률 99.99%

병목 분석: t3.large 버스터블 인스턴스 특성상 지속 부하 시 CPU 크레딧 소진 -> 스로틀링 발생

nginx : 41.5% CPU
app1  : 40.2% CPU
app2  : 33.9% CPU
합계  : ~115% (2코어 = 200% 기준)
st    : 5.4%  <- CPU 크레딧 소진으로 스로틀링

실제 서비스라면 서비스별 인스턴스 분리 (RDS, ElastiCache, MSK, OpenSearch) + c5 계열 (비버스터블) 필요

Clone this wiki locally