
초기에는 모든 서비스를 EC2 인스턴스 한 대에 구성하여 운영하고 있었습니다.
Spring 애플리케이션, HAProxy, Nginx Proxy Manager, MySQL, Redis까지 모두 하나의 인스턴스에 올려둔 구조였습니다.
이러한 구성은 초기 개발 및 테스트 단계에서는 빠르게 서비스를 구축할 수 있다는 장점이 있었지만,
JMeter 부하 테스트를 진행하면서 심각한 성능 저하 문제를 발견하게 되었습니다.
부하 테스트 결과, 다음과 같은 문제가 발생했습니다.
당시 측정된 TPS는 최대 약 120이었지만,
이는 서버 자원이 과부하된 상태에서 비정상적으로 부하를 받아낸 결과였습니다.
(실제 응답 지연 및 503 오류가 빈번하게 발생했습니다.)
테스트는 JMeter를 이용해 다음과 같은 설정으로 진행했습니다.
성능 문제의 핵심 원인은
단일 인스턴스에 과도하게 많은 역할이 집중되어 리소스 경합이 심했던 점이었습니다.
따라서 다음과 같은 개선 작업을 수행했습니다.
DB 서버 분리
애플리케이션 서버 튜닝
DB 서버용 보안 그룹과 EC2 인스턴스는 다음과 같이 정의했습니다.
resource "aws_security_group" "sg_db" {
name = "${var.prefix}-sg-db"
vpc_id = aws_vpc.vpc_1.id
ingress {
description = "MySQL"
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "Redis"
from_port = 6379
to_port = 6379
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
⚠️ 주의: 현재는 더미 데이터 삽입 및 테스트를 위해 퍼블릭 접속을 허용했지만,
운영 환경에서는 반드시 VPC 내부 통신만 허용하는 것이 좋습니다.
인스턴스 생성 시 user_data를 이용해 다음 작업을 자동화했습니다.
.env 파일 작성 및 환경변수 설정docker-compose -f db-docker-compose.yml up -d
초기에는 Amazon Linux 2023의 최신 AMI를 자동으로 조회하여 사용했습니다.
data "aws_ami" "latest_amazon_linux" {
most_recent = true
owners = ["amazon"]
}
그러나 이 방식은 Terraform을 적용할 때마다 새로운 AMI로 인해 인스턴스가 교체되는 문제가 발생했습니다.
따라서 특정 AMI ID를 고정하여 인프라를 안정적으로 관리할 수 있도록 개선했습니다.
mysqldump 명령어를 이용해 기존 인스턴스의 데이터를 백업한 뒤,
신규 DB 서버로 복원 작업을 진행했습니다.
Spring 애플리케이션 설정 파일(application.yml)의
DB 호스트 및 포트 정보도 신규 인스턴스 기준으로 수정하여 재배포를 완료했습니다.
DB 서버 분리와 함께 HikariCP 커넥션 풀 최적화, 모니터링 시스템 구축을 완료한 후,
동일한 조건으로 부하 테스트를 재진행했습니다.
TPS 수치는 이전보다 낮아졌지만,
서버는 이제 지속 가능한 처리량을 안정적으로 유지할 수 있는 상태로 개선되었습니다.
| 항목 | DB 분리 전 (튜닝 전) | DB 분리 후 + 시스템 튜닝 |
|---|---|---|
| TPS | 120 | 37 |
| 응답 안정성 | 불안정 (오류 빈발) | 안정적 (오류 없음) |
| CPU 사용률 | 급등, 불안정 | 정상 범위 유지 |
| Connection Pool 설정 | max size 10 | max size 5 |
| 모니터링 시스템 | 미구축 | 구축 완료 |