Docker 메모리 고갈 문제 및 최적화 - lets-go-trip/treaXure-backend GitHub Wiki
-
증상: Docker 컨테이너가
Thread starvation경고 후 강제 종료 - 원인: EC2 t2.micro (1GB RAM)에서 JVM이 1024MB 힙 사용 → 메모리 고갈
-
근본 원인:
Thread starvation or clock leap detected는 CPU/메모리 리소스 부족의 신호
# 변경 전: -Xms512m -Xmx1024m
# 변경 후: -Xms128m -Xmx300m (70% 절약)
# docker-compose.yml 추가
deploy:
resources:
limits:
memory: 512M
reservations:
memory: 256M
# 변경 전: eclipse-temurin:21-jdk (무거움)
# 변경 후: eclipse-temurin:21-jre-alpine (경량)
docker run -d --name treaxure-optimized
--memory="512m" --memory-swap="768m"
--restart=always -p 8081:8081 treaxure-optimized:latest
| 항목 | 이전 | 현재 | 개선 효과 |
|---|---|---|---|
| JVM 최대 힙 | 1024MB | 300MB | 70% 절약 |
| 컨테이너 메모리 | 제한없음 | 358MB/512MB | 69% 사용률 |
| 시스템 여유 메모리 | ~0MB | 142MB | 안정성 확보 |
| CPU 사용률 | 높음 | 0.10% | 매우 안정 |
cd ~/dev-environment
# 컨테이너 정리 (필요시)
docker stop treaxure-optimized 2>/dev/null || true
docker rm treaxure-optimized 2>/dev/null || true
# 최적화된 컨테이너 실행
docker run -d --name treaxure-optimized
--memory="512m" --memory-swap="768m"
--restart=always
-p 8081:8081
treaxure-optimized:latest
cd ~/dev-environment
# 환경변수 파일 준비 (필요시)
# .env 파일이 있다면
# 컴포즈로 실행
docker-compose up -d backend
# 또는 전체 서비스
docker-compose up -d
cd ~/dev-environment
# 기존 정리
docker stop treaxure-optimized && docker rm treaxure-optimized
# 새 이미지 빌드
docker build -f Dockerfile.backend -t treaxure-optimized .
# 실행
docker run -d --name treaxure-optimized
--memory="512m" --memory-swap="768m"
--restart=always -p 8081:8081 treaxure-optimized:latest
# 30초마다 컨테이너 상태 체크
watch -n 30 'docker stats treaxure-optimized --no-stream'
# 출력 예시:
# CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM %
# 230ee4619d2a treaxure-optimized 0.10% 358.1MiB / 512MiB 69.95%
# 실시간 로그 확인
docker logs -f treaxure-optimized
# 경고 로그만 필터링
docker logs -f treaxure-optimized | grep -E "starvation|OutOfMemory|ERROR|WARN"
# 최근 50줄 로그 확인
docker logs treaxure-optimized --tail 50
# 시스템 메모리 사용량
free -h
# 디스크 사용량 (100% 방지)
df -h
# Docker 디스크 정리 (필요시)
docker system prune -f
# API 응답 확인
curl -s <http://localhost:8081/swagger-ui/index.html> | head -3
# 컨테이너 상태 확인
docker ps | grep treaxure-optimized
# 애플리케이션 포트 확인
netstat -tulpn | grep 8081
-
메모리 사용률 > 90%:
docker stats에서 확인 - Thread starvation 로그: 리소스 부족 신호
-
컨테이너 재시작 반복:
docker ps상태 확인 -
API 응답 없음:
curl테스트 실패
# 1. 긴급 재시작
docker restart treaxure-optimized
# 2. 리소스 확인
docker stats treaxure-optimized --no-stream
free -h
# 3. 로그 점검
docker logs treaxure-optimized --tail 100 | grep -E "ERROR|FATAL|OutOfMemory"
# 4. 완전 재배포 (최후 수단)
docker stop treaxure-optimized && docker rm treaxure-optimized
docker run -d --name treaxure-optimized
--memory="512m" --memory-swap="768m"
--restart=always -p 8081:8081 treaxure-optimized:latest
-
docker ps- 컨테이너 실행 상태 -
docker stats --no-stream- 메모리 사용률 < 80% -
free -h- 시스템 여유 메모리 > 100MB -
curl <http://localhost:8081/swagger-ui/index.html> - API 응답 확인
-
docker logs treaxure-optimized | grep -c ERROR- 에러 로그 수 -
df -h- 디스크 사용률 < 90% -
docker system df- Docker 디스크 사용량
# Docker 정리 (디스크 부족시)
docker system prune -f
로그 정리 (용량 큰 경우)
docker logs treaxure-optimized 2>/dev/null | wc -l # 로그 줄 수 확인
# 많다면 컨테이너 재시작으로 로그 초기화
-
EC2 업그레이드:
t2.micro→t3.micro(더 나은 CPU 크레딧) - 모니터링 도구: CloudWatch 또는 Prometheus 도입 → cloudwatch 도입 완료
- 자동 재시작: systemd 서비스로 Docker 관리
- 백업 전략: 정기적 DB 백업 및 이미지 백업