[AWS] EC2 서버 용량 문제 해결하기

2025. 5. 13. 14:00·AWS

이전 글: [AWS] React + Spring Boot(Maven) 프로젝트 AWS EC2(Ubuntu)에 빌드 및 배포하기

이전 포스팅에서 진행했던 배포 과정이 처음에는 정상적으로 작동하는 것을 확인했으나, 오늘 낮에 다시 접속해보니 웹사이트에 연결이 되지 않는 상황이 발생했다. 더 이상한 점은 로컬 환경에서도 데이터베이스 연결이 안 되기 시작했다는 것이다. 처음에는 네트워크 문제나 설정 오류라고 생각했으나, 점점 EC2 인스턴스의 용량 문제가 의심되기 시작했다. 이 글에서는 AWS EC2 인스턴스에서 발생한 메모리 부족 문제를 진단하고 해결한 과정을 상세히 설명하고자 한다.

 

1. 문제 진단하기

이전 포스팅에서 배포했던 애플리케이션에 접속이 되지 않아 확인해보니, DB 연결이 끊겨 있었다. 로컬 환경에서도 동일하게 데이터베이스 연결이 실패하는 현상이 발생했다. EC2 인스턴스에 저장된 DB가 응답하지 않는 것으로 보였다.

EC2 인스턴스에 SSH로 접속을 시도했으나, 접속이 매우 느리거나 아예 되지 않는 상황이 발생했다. 여러 번의 시도 끝에 접속이 되었지만, 시스템이 매우 느리게 반응했다. 이 시점에서 메모리나 디스크 공간 부족 문제를 의심하게 되었다.

문제 해결을 위해 AWS 콘솔에서 인스턴스를 중지하고 다시 시작했다. 이 과정에서 인스턴스의 IP 주소가 변경되었는데, 이는 EC2의 일반적인 특성이다. 재시작 후 새로운 IP로 접속했지만, 여전히 시스템은 느리게 동작했다.

 

2. 시스템 정리 및 모니터링

다시 SSH로 접속한 후, 기존에 배포했던 JAR 파일을 확인했다.

ls -la /home/ubuntu/

 

용량 문제 해결을 위해 기존 JAR 파일을 삭제하기로 결정했다.

rm /home/ubuntu/idea-backend-0.0.1-SNAPSHOT.jar

 

이렇게 JAR 파일을 삭제한 후에도 문제의 근본 원인을 찾기 위해 더 자세한 시스템 모니터링이 필요했다.

기존에는 Windows CMD를 사용해 SSH 접속을 했으나, 보다 상세한 시스템 모니터링을 위해 MobaXterm으로 접속 방식을 변경했다. MobaXterm은 SSH 연결뿐만 아니라 시스템 리소스 모니터링 기능도 제공해 현재 서버 상태를 실시간으로 확인할 수 있는 장점이 있다.

 

SSH 로그인 시에는 선택한 AMI(Amazon Machine Image)에 따라 기본 사용자명이 다르므로 주의해야 한다.

  • Amazon Linux: ec2-user
  • Ubuntu: ubuntu
  • RHEL: ec2-user 또는 root
  • CentOS: centos

등 AMI별로 기본 사용자명이 다르게 설정되어 있다.

본 글에서는 Ubuntu를 사용했기 때문에 ubuntu 사용자로 접속했다.

 

MobaXterm으로 접속한 후 리소스 모니터링 패널을 활성화했더니, 메모리 사용량이 매우 높은 것을 확인할 수 있었다.

0.70 GB / 0.93 GB

 

t2.micro 인스턴스는 1GB RAM을 제공하는데, 이미 700MB가 사용 중인 상태였다. 또한 로그 파일을 확인해보니 지속적으로 쌓이고 있었다.

ls -lh app.log
-rw-rw-r-- 1 ubuntu ubuntu 245K May 12 06:06 app.log

 

문제 진단 결과, 다음 두 가지 핵심 이슈를 발견했다.

  1. 메모리(RAM) 부족으로 인한 성능 저하
  2. 로그 파일이 계속 쌓이면서 디스크 공간을 점유

 

3. 스왑 메모리 설정

메모리 부족 문제를 해결하기 위해 디스크 공간을 가상 메모리로 활용하는 스왑(Swap) 메모리를 설정했다. 원래는 EC2 인스턴스 유형을 t2.small이나 t2.medium으로 업그레이드하는 것이 가장 좋은 해결책이지만, 프리티어를 벗어나면 비용이 발생하기 때문에 비용 효율적인 대안으로 스왑 메모리 설정을 선택했다. 다음과 같은 단계로 4GB의 스왑 메모리를 구성했다.

# 1. 4GB 스왑 파일 생성
sudo fallocate -l 4G /swapfile

# 2. 권한 설정 (보안 강화)
sudo chmod 600 /swapfile

# 3. 스왑 파일 포맷
sudo mkswap /swapfile

# 4. 스왑 파일 활성화
sudo swapon /swapfile

# 5. 부팅 시 자동 마운트 설정
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# 6. 스왑 설정 확인
free -h

 

설정 후 아래 명령어로 확인해보니 다음과 같이 스왑 메모리가 추가된 것을 확인할 수 있었다.

# 메모리 확인
free -h
              total        used        free      shared  buff/cache   available
Mem:          957Mi       766Mi        65Mi        91Ki        91Mi       205Mi
Swap:         4.0Gi          0B       4.0Gi

이제 실제 메모리 1GB와 스왑 메모리 4GB를 합쳐 총 5GB의 메모리를 사용할 수 있게 되었다.

 

스왑 메모리 사용의 장단점

장점

  • 비용 발생 없이 가용 메모리를 늘릴 수 있다
  • 인스턴스 유형 변경 없이 즉시 적용 가능하다
  • 인스턴스 재시작 없이 설정 가능하다
  • 급격한 메모리 사용량 증가에도 시스템 안정성을 유지할 수 있다

단점

  • 디스크 I/O를 사용하기 때문에 실제 RAM보다 성능이 현저히 떨어진다
  • 디스크 읽기/쓰기가 증가하여 SSD의 수명이 단축될 수 있다
  • 많은 스왑 사용 시 전체적인 시스템 성능이 저하될 수 있다
  • 근본적인 해결책이 아니라 임시방편적 성격이 강하다

 

4. 로그 파일 관리 설정

다음으로 로그 파일이 무한정 쌓이는 것을 방지하기 위해 logrotate를 설정했다:

# 현재 로그 파일 크기 확인
ls -lh app.log

# 로그 파일 비우기
truncate -s 0 app.log

# logrotate 설치
sudo apt install logrotate

# 설정 파일 생성
sudo nano /etc/logrotate.d/springboot

 

설정 파일에는 다음과 같은 내용을 추가했다.

/home/ubuntu/app.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 0640 ubuntu ubuntu
    size 10M
}

이 설정은 로그 파일이 10MB에 도달하거나 매일 자정에 로그 파일을 교체하고, 최대 7일치만 보관하도록 한다. 이를 통해 디스크 공간을 효율적으로 관리할 수 있게 되었다.

 

5. 애플리케이션 재배포

재배포를 위해 먼저 실행 중인 Java 프로세스를 종료했다.

# 실행 중인 Java 프로세스 확인
ps aux | grep java

# 프로세스 ID를 확인하고 필요시 강제 종료
kill -9 [프로세스ID]

 

JAR 파일을 다시 EC2 인스턴스에 업로드하고 실행했다. MobaXterm의 SFTP 기능을 사용하여 손쉽게 파일을 드래그 앤 드롭으로 업로드했다. 이번에는 메모리 부족 문제가 발생하지 않도록 Java 힙 메모리 크기를 2GB로 설정하여 실행했다.

# 파일 업로드 확인
ls -la

# 2GB 메모리 제한으로 JAR 파일 실행
nohup java -Xmx2048m -jar idea-backend-0.0.1-SNAPSHOT.jar > app.log 2>&1 &

 

여기서 -Xmx2048m 옵션은 Java 힙 메모리의 최대 크기를 2GB로 제한하는 설정이다. 이전에는 기본값이나 512MB로 설정되어 있어 메모리 부족 문제가 발생했을 가능성이 크다.

실행 후 로그를 확인하여 정상 작동하는지 확인했다.

tail -f app.log

 

마무리

이번 경험을 통해 AWS EC2의 t2.micro 인스턴스와 같은 작은 규모의 서버에서 메모리 관리가 얼마나 중요한지 깨달았다. 특히 Spring Boot와 같은 Java 기반 애플리케이션은 메모리 사용량이 상당하기 때문에 적절한 관리가 필요하다.

핵심 해결책은 다음과 같았다.

  1. 스왑 메모리 설정: 물리적 메모리(RAM)가 부족할 때 디스크 공간을 활용하여 가상 메모리를 추가
  2. 로그 파일 관리: logrotate를 통해 로그 파일이 무한정 커지는 것을 방지
  3. 적절한 메모리 할당: Java 애플리케이션에 적정 수준의 메모리 제한 설정

또한 MobaXterm과 같은 도구를 활용하여 서버 리소스를 실시간으로 모니터링하는 것이 문제 진단에 큰 도움이 되었다. 이전에는 단순히 연결 문제를 의심했으나, 리소스 모니터링을 통해 정확한 원인을 파악할 수 있었다.

이러한 최적화 작업은 AWS에서 도커나 복잡한 인프라 없이도 소규모 프로젝트를 효율적으로 운영할 수 있게 해준다. 물론 장기적으로는 t2.small이나 t2.medium과 같은 더 큰 인스턴스로 업그레이드하거나, Elastic IP를 설정하여 IP 주소가 변경되는 문제를 해결하는 것도 고려해볼 만하다.

'AWS' 카테고리의 다른 글

[AWS] EC2에서 Nginx로 포트 번호 없이 웹 서비스 배포하기  (0) 2025.05.16
[AWS] Docker와 GitHub Actions를 활용한 CI/CD 파이프라인 구축과 환경 변수 문제 해결  (0) 2025.05.15
[AWS] Windows에서 AWS EC2까지: Docker로 Python 서비스 배포하기  (0) 2025.05.14
[AWS] React + Spring Boot(Maven) 프로젝트 AWS EC2(Ubuntu)에 빌드 및 배포하기  (0) 2025.05.12
[AWS] EC2(Ubuntu)에 MySQL 설치하고 스프링부트와 연결하기  (0) 2025.04.25
'AWS' 카테고리의 다른 글
  • [AWS] Docker와 GitHub Actions를 활용한 CI/CD 파이프라인 구축과 환경 변수 문제 해결
  • [AWS] Windows에서 AWS EC2까지: Docker로 Python 서비스 배포하기
  • [AWS] React + Spring Boot(Maven) 프로젝트 AWS EC2(Ubuntu)에 빌드 및 배포하기
  • [AWS] EC2(Ubuntu)에 MySQL 설치하고 스프링부트와 연결하기
dud9902
dud9902
개발자 취준생 기록일지
  • dud9902
    dud's DevStory
    dud9902
  • 전체
    오늘
    어제
    • 분류 전체보기 (79)
      • SpringBoot (14)
      • React (12)
      • Python (14)
      • AI (21)
      • DB (5)
      • Figma (1)
      • Markdown (1)
      • AWS (6)
      • 기타 (5)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    스프링부트
    redis
    Agent
    miniforge
    pydantic
    AWS
    의존성 주입
    AI
    CrewAI
    db
    react
    twilio
    SQLAlchemy
    docker
    springboot
    FastAPI
    pytorch
    langchain
    Python
    recognize anything
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
dud9902
[AWS] EC2 서버 용량 문제 해결하기
상단으로

티스토리툴바