2025. 6. 1. 13:38ㆍ인프라
Spring Boot 애플리케이션을 리눅스 운영 서버에 배포하는 방법은 여러 가지가 있지만, 운영 환경에서 안정적으로 관리할 수 있는 구조로 구성하려면 다음과 같은 방식으로 설정하는 것을 권장합니다.
✅ 1. 준비물 체크리스트
- 리눅스 서버 (예: Amazon Linux, Ubuntu 등)
- JDK 설치 (Spring Boot가 사용하는 버전, 예: JDK 17)
- Spring Boot 애플리케이션 .jar 파일
- DB 접근 가능 (외부 RDS 또는 서버 내 설치)
- (선택) 리버스 프록시용 Nginx
- (선택) 시스템 자동 실행을 위한 systemd 서비스 등록
✅ 2. 서버 환경 세팅
1) JDK 설치
예: Amazon Corretto 17 설치
sudo yum install java-17-amazon-corretto -y
설치 확인:
java -version
2) 애플리케이션 배포 디렉토리 생성
sudo mkdir -p /opt/myapp
sudo chown ec2-user:ec2-user /opt/myapp
3) .jar 파일 복사
scp build/libs/myapp.jar ec2-user@<서버주소>:/opt/myapp/
4) 실행 스크립트 작성 (옵션)
# /opt/myapp/start.sh
#!/bin/bash
nohup java -jar /opt/myapp/myapp.jar --spring.profiles.active=prod > /opt/myapp/app.log 2>&1 &
echo $! > /opt/myapp/app.pid
종료 스크립트도 추가:
# /opt/myapp/stop.sh
#!/bin/bash
kill $(cat /opt/myapp/app.pid)
스크립트에 실행 권한 부여:
chmod +x /opt/myapp/*.sh
✅ 3. systemd 서비스로 등록 (권장)
sudo nano /etc/systemd/system/myapp.service
[Unit]
Description=My Spring Boot Application
After=network.target
[Service]
User=ec2-user
ExecStart=/usr/bin/java -jar /opt/myapp/myapp.jar --spring.profiles.active=prod
SuccessExitStatus=143
Restart=always
RestartSec=10
StandardOutput=file:/opt/myapp/app.log
StandardError=file:/opt/myapp/app.err.log
[Install]
WantedBy=multi-user.target
명령어로 서비스 등록:
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
상태 확인:
sudo systemctl status myapp
✅ 4. Nginx로 리버스 프록시 설정 (선택)
sudo yum install nginx -y
sudo nano /etc/nginx/conf.d/myapp.conf
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
sudo nginx -t
sudo systemctl restart nginx
✅ 5. 기타 팁
- 환경 설정: application-prod.yml을 만들어서 운영 설정 분리
- 보안: 방화벽 설정 (예: 22, 80, 443 포트만 열기)
- 모니터링: top, htop, 로그 파일 등으로 확인
- 로그 관리: logrotate 설정으로 로그 크기 제어 가능
EC2 하나에 WAS(Spring Boot)와 Redis를 같이 올리는 것 자체는 가능하지만, 운영환경에서는 위험할 수 있습니다. 아래에 이유와 고려사항을 정리해드릴게요.
✅ 1. 서버가 죽을 수 있는 이유
① 리소스 경쟁 (CPU / 메모리)
- WAS(Spring Boot)는 메모리를 많이 사용할 수 있으며, Redis도 메모리를 기반으로 작동합니다.
- 둘 다 메모리를 많이 사용하면 메모리 부족(OOM) 으로 EC2 인스턴스 전체가 불안정해질 수 있습니다.
- 특히 Redis는 모든 데이터를 메모리에 올리는 구조라, WAS에서 GC가 동작하거나 Redis의 캐시가 커지면 서버가 뻗을 수 있습니다.
② 서비스 충돌 및 포트 충돌
- Redis 기본 포트는 6379, Spring Boot는 8080인데, 운영 중 설정이 꼬이거나 충돌나면 장애가 발생할 수 있습니다.
③ 장애 격리 불가
- Redis에 문제가 생기면 같은 서버에 있는 WAS도 영향을 받을 수 있고 반대도 마찬가지입니다.
- 즉, 장애가 한쪽에서 발생하면 전체가 죽을 가능성이 높아짐.
④ 유지보수 어려움
- 리눅스 시스템이나 Redis 버전 업그레이드가 필요한 경우, Spring Boot WAS도 중단되어야 할 수 있습니다.
✅ 2. 추천 아키텍처 (운영 기준)
구성 설명
EC2 #1 | WAS(Spring Boot) 전용 |
EC2 #2 또는 ElastiCache | Redis 전용 서버 or AWS ElastiCache 사용 |
S3 | 정적 파일 (이미지 등) 저장 |
RDS | DB 분리 운영 |
AWS에서는 Redis는 ElastiCache 로 관리하는 것이 안정성과 성능 면에서 매우 유리합니다.
✅ 3. 예외적으로 함께 써도 괜찮은 경우
- 개발/테스트 환경
- 트래픽이 적은 내부 시스템
- 비용을 절감해야 하는 초기 스타트업
이런 경우엔 같이 써도 되지만, 메모리 리밋, CPU 모니터링, 스왑 설정 등을 잘 조절해야 합니다.
✅ 4. 해결책 / 안전장치
- EC2 메모리를 여유 있게 설정 (예: 최소 4GB 이상)
- Redis maxmemory 설정으로 메모리 제한
- Spring Boot JVM heap size 제한 (-Xmx512m 등)
- CloudWatch로 메모리/CPU 모니터링 설정
- Redis 백업 및 장애 시 재시작 스크립트 구성
✅ 요약
질문 답변
EC2 하나에 WAS + Redis 같이 써도 되나요? | 가능하지만 운영환경에서는 위험 |
죽을 수 있나요? | 예, 리소스 부족 등으로 서버 전체 다운 가능성 있음 |
더 좋은 방법은? | Redis는 ElastiCache, WAS는 EC2 또는 ECS로 분리 운영 |
운영환경에서도 트래픽이 많지 않거나, 비용 제약이 있는 경우에는 하나의 EC2에 WAS(Spring Boot) 와 Redis 를 함께 올려서 사용할 수 있습니다.
다만 안정성을 확보하기 위해 자원 분리와 리소스 제한 설정이 중요합니다.
✅ 하나의 EC2에 WAS(Spring Boot) + Redis 설정 가이드
📌 기본 전제
- Amazon Linux 2 또는 Ubuntu
- EC2 메모리 최소 2~4GB 이상
- Spring Boot .jar 배포 준비됨
✅ 1. Redis 설치
[Amazon Linux 2 기준 예시]
sudo yum update -y
sudo amazon-linux-extras enable redis6
sudo yum install redis -y
설정 파일 열기:
sudo nano /etc/redis/redis.conf
필수 설정 변경:
bind 127.0.0.1
protected-mode yes
maxmemory 256mb
maxmemory-policy allkeys-lru
서비스 등록 및 실행:
sudo systemctl enable redis
sudo systemctl start redis
sudo systemctl status redis
💡 maxmemory로 Redis가 사용할 수 있는 메모리 제한을 설정하세요. 시스템 다운 방지에 중요합니다.
✅ 2. Spring Boot 애플리케이션 설정
application-prod.yml 또는 application.properties
spring:
data:
redis:
host: localhost
port: 6379
✅ 3. Spring Boot 실행 시 자원 제한
실행 스크립트 예시 (start.sh)
#!/bin/bash
JAVA_OPTS="-Xms512m -Xmx512m"
nohup java $JAVA_OPTS -jar /opt/myapp/myapp.jar --spring.profiles.active=prod > /opt/myapp/app.log 2>&1 &
- -Xmx512m으로 WAS가 너무 많은 메모리를 쓰지 않게 제한합니다.
✅ 4. 시스템 안정성 설정 (권장)
1) redis와 was를 각각 systemd 서비스로 등록하여 자동 재시작 가능하게 설정
예시:
sudo nano /etc/systemd/system/myapp.service
[Unit]
Description=Spring Boot App
After=network.target redis.service
[Service]
ExecStart=/usr/bin/java -Xmx512m -jar /opt/myapp/myapp.jar --spring.profiles.active=prod
Restart=always
User=ec2-user
StandardOutput=file:/opt/myapp/app.log
StandardError=file:/opt/myapp/app-error.log
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
✅ 5. 모니터링 도구 설치 (옵션)
- htop으로 실시간 메모리/CPU 확인
- CloudWatch Agent 설치하여 AWS에서 모니터링
- Redis 상태 점검: redis-cli info
✅ 추천: 메모리 제한 요약
구성 요소 메모리 제한 예시
Redis | maxmemory 256mb |
WAS | -Xmx512m JVM 제한 |
EC2 총 메모리 | 최소 2~4GB 권장 |
✅ 정리
항목 설명
가능 여부 | ✅ 하나의 EC2에 WAS + Redis 가능 |
주의점 | CPU/메모리 자원 경쟁 주의 |
필수 설정 | Redis maxmemory, JVM -Xmx, 모니터링 |
권장 OS 도구 | systemd, htop, redis-cli, CloudWatch |
EC2의 총 메모리가 1GB인 경우, **WAS(Spring Boot)**와 Redis를 함께 운영하는 것은 가능은 하지만 매우 제한적인 환경입니다.
서버가 뻗을 가능성도 높기 때문에, 아래의 사항들을 반드시 고려해서 자원 절약형 설정으로 구성해야 합니다.
⚠️ 1GB 메모리에서의 주요 위험
위험 요소 설명
OOM 발생 | WAS 또는 Redis가 메모리를 초과 사용하면 서버가 다운될 수 있음 (OutOfMemory) |
스왑 사용 | RAM 부족 시 디스크 스왑 사용 → 속도 급격히 느려짐 |
GC 압박 | JVM이 적은 메모리에서 빈번하게 GC → 성능 저하 |
Redis 데이터 유실 | Redis가 캐시 데이터를 유지 못하고 자주 휘발될 수 있음 |
✅ 현실적인 설정 전략 (1GB 환경 전용)
📌 1. Redis 제한 설정
sudo nano /etc/redis/redis.conf
maxmemory 128mb
maxmemory-policy allkeys-lru
- 128MB 이상 절대 주지 마세요.
- noeviction은 비추천, allkeys-lru 또는 volatile-lru 권장
📌 2. Spring Boot JVM 메모리 제한
java -Xmx256m -Xms256m -jar your-app.jar
- Xmx와 Xms를 모두 256m로 고정
- 필요 시 -XX:+UseSerialGC 옵션으로 GC 부담 줄일 수 있음
java -Xms256m -Xmx256m -XX:+UseSerialGC -jar your-app.jar
📌 3. EC2에 스왑 메모리 추가 (권장)
sudo dd if=/dev/zero of=/swapfile bs=1M count=1024
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab
✅ 스왑은 느리지만, OOM을 막는 최소한의 방어막입니다.
📌 4. EC2 인스턴스 종류 변경 고려
인스턴스 메모리 월 요금 (서울 리전 기준, 2025)
t3.micro | 1GB | $7~8 |
t3.small | 2GB | $13~14 |
t3.medium | 4GB | $26~27 |
💡 한 달에 몇 천 원 정도 더 쓰면 훨씬 안정적으로 운영 가능해집니다.
✅ 최종 요약
항목 설정값 (1GB 환경)
Redis maxmemory | 128MB |
JVM 힙 설정 | -Xmx256m -Xms256m -XX:+UseSerialGC |
EC2 스왑 추가 | 필수 |
모니터링 | htop, redis-cli info, top, 로그 주기적 확인 |
용도 | 프로토타입, 저부하 운영, 테스트용에 적합 |
운영 권장 | ❌ 아니요, 운영환경에는 메모리 2GB 이상 권장 |
필요하시면 EC2 자동 스왑 설정, Spring Boot 경량화 팁, 또는 ElastiCache로 Redis 분리 운영 방법도 안내드릴게요.
계속 1GB로 운영하셔야 하는 상황인지, 아니면 확장 가능한지 알려주시면 더 맞춤형으로 도와드릴 수 있습니다.
Redis 없이 WAS(Spring Boot) 자체 세션만 사용하는 구조라면 1GB 메모리로도 충분히 운영 가능합니다, 단 다음 조건이 충족된다면요:
✅ 충분히 가능한 조건
조건 설명
트래픽이 많지 않다 | 일일 사용자 수가 적거나 테스트/개발용 서버 |
세션 데이터가 작다 | 사용자별 세션에 큰 데이터 저장하지 않음 |
백그라운드 작업이 많지 않다 | 대용량 배치나 큐 작업 등 없음 |
외부 DB 사용 | 애플리케이션이 DB를 별도로 두고 있고, 모든 데이터 저장을 메모리에 하지 않음 |
✅ Spring Boot 내장 세션의 특징
Spring Boot는 기본적으로 HttpSession을 메모리에 저장합니다 (서버 메모리 세션).
이 방식은 간단하고 빠르지만, 다음과 같은 제약이 있습니다:
장점:
- Redis 등 외부 세션 저장소 없이 구성 가능
- 트래픽이 적을 때는 매우 가볍고 빠름
단점:
- WAS 재시작 시 세션 모두 사라짐
- 서버가 여러 대가 되면 세션 공유 안 됨 (Sticky Session 또는 Redis 필요)
- 서버가 죽으면 로그인 등 상태 유지 불가
✅ JVM 자원 관리 팁 (1GB 서버 기준)
java -Xms512m -Xmx512m -XX:+UseSerialGC -jar yourapp.jar
이렇게 설정하면 Spring Boot가 너무 많은 메모리를 쓰지 않도록 제한할 수 있습니다.
✅ 정리: Redis 없이 운영할 수 있는가?
항목 가능 여부 설명
Redis 없이 WAS에서만 세션 저장 | ✅ 가능 | 단일 서버, 적은 트래픽에 적합 |
1GB 메모리로 운영 | ✅ 가능 | JVM Heap 제한, 스왑 추가 시 안정성 확보 |
세션 유지 | ✅ WAS 재시작 전까진 세션 유지됨 | |
Redis 필요 여부 | ❌ 초기에 굳이 필요 없음 | 운영환경에서 스케일 아웃 시 필요해질 수 있음 |
🚀 추천 구성 (1GB 환경)
- Redis 없이 시작
- EC2 1GB 인스턴스에서 JVM 제한하여 Spring Boot 단독 실행
- 필요 시 스왑 설정 (/swapfile)
- 세션 분산이 필요해지면 Redis 도입 (ElastiCache 또는 별도 EC2)
추가로 도움이 필요하시면:
- JVM 힙 자동 조정 스크립트
- Spring Session 설정 없이 세션 유지 팁
- 트래픽 증가 시 확장 전략
도 도와드릴 수 있습니다.
원하시면 위 항목 중 바로 알려드릴게요.
Spring Boot로 만든 WAS(Web Application Server, 즉 애플리케이션 자체)는 기본적으로 JVM 위에서 실행되므로, 사용하는 메모리는 JVM 힙 메모리 + JVM 외 메모리(메타영역, 버퍼 등) 로 나눠집니다.
✅ 기본 메모리 사용량 (제한하지 않았을 경우)
항목 설명 대략적인 크기
JVM 힙(Heap) | 객체를 저장하는 메모리 공간 | |
Metaspace | 클래스 메타데이터 저장 | 50~100MB 이상 |
Thread Stack | 각 스레드마다 생성됨 (기본 512KB~1MB) | 수십 MB |
기타 | GC, 클래스 로더, 네이티브 코드 등 | 수십 MB |
👉 결과적으로:
아무 설정 없이 Spring Boot 앱을 실행하면
최소 200~300MB, 많게는 500~800MB 이상 메모리를 사용하는 경우가 많습니다.
✅ 예시: 아무 JVM 옵션 없이 실행할 경우
java -jar your-app.jar
- 기본적으로 힙 사이즈는 총 메모리의 약 1/4~1/2까지 자동 확장됨
- EC2 메모리가 1GB면, 최대 ~512MB 이상까지 JVM 힙이 커질 수 있음
- 결국 전체 사용량은 700MB 이상 될 수 있음 → 여유 메모리 없어지고, OOM 위험
✅ 추천 설정: 메모리 제한하기
java -Xms256m -Xmx256m -XX:+UseSerialGC -jar your-app.jar
옵션 설명
-Xms | JVM 초기 힙 크기 |
-Xmx | JVM 최대 힙 크기 |
-XX:+UseSerialGC | 메모리가 적을 때 적합한 GC 방식 (단일 스레드, 경량) |
👇 이 설정을 쓰면:
- WAS 메모리 사용량을 약 300~400MB 선으로 제한할 수 있음
- EC2 1GB 메모리에서도 Redis 없이 안정적으로 구동 가능
✅ htop 등에서 보는 실제 사용량
만약 htop이나 top 명령어로 JVM 프로세스를 보면, 설정 안 했을 경우 다음처럼 나옵니다:
PID %MEM COMMAND
1234 45.2 java -jar your-app.jar
→ 이건 약 450MB 정도를 사용하는 걸 의미함 (즉, 메모리 절반 이상을 씀)
✅ 정리
질문 답변
Spring Boot WAS는 기본적으로 메모리를 얼마나 사용하나요? | 제한 안 하면 보통 300MB~800MB 정도 |
EC2 1GB에서 그냥 실행해도 되나요? | ❌ 위험. 반드시 JVM 힙 제한 필요 |
최소 메모리 설정은 어떻게 하나요? | -Xmx256m -Xms256m -XX:+UseSerialGC 추천 |
스프링부트로 개발된 프로젝트를 리눅스에 WAS서버를 실행할 경우 WAS서버가 자동으로 서버의 메모리를 제한하는가?
✅ 결론 먼저
❌ "설정 안 하면 1GB 이내로 자동 조절되는 건 아니다"
✅ 설정 안 하면 Java는 가능한 만큼 메모리를 먹으려고 한다.
즉, EC2 메모리가 1GB라고 해서 JVM이 알아서 그 안에 맞게 조절해 주지 않습니다.
오히려 Java는 기본적으로 자유롭게 힙을 늘려 쓰기 때문에, EC2가 1GB면 금방 메모리를 다 써버려서 OOM(Out Of Memory) 이 날 수 있습니다.
🔍 왜 그럴까? (JVM 기본 동작)
Spring Boot를 아무 설정 없이 실행하면 JVM은 대략 아래처럼 힙 크기를 자동 설정합니다:
JVM 힙 관련 기본값 (예시)
-Xms (초기 힙) | 자동 (보통 1/64 메모리) |
-Xmx (최대 힙) | 자동 (보통 1/4 ~ 1/2 메모리) |
즉, EC2 메모리 1GB면 JVM 힙 최대 크기를 ~512MB 이상까지 쓸 수 있도록 해버립니다.
그리고 이 외에도:
- 메타스페이스 (50~100MB)
- GC 버퍼
- 스레드 스택 등
→ 전체 합치면 700MB~900MB까지도 쉽게 넘어감
✅ 그래서 어떻게 해야 하나?
반드시 JVM 힙 메모리 제한을 줘야 합니다:
java -Xms256m -Xmx256m -XX:+UseSerialGC -jar your-app.jar
이렇게 하면:
항목 사용량
JVM 힙 | 최대 256MB |
기타 JVM 자원 | 100~200MB |
전체 메모리 사용량 | 약 300~400MB 선으로 제한 가능 |
✅ 정리
질문 답변
JVM이 알아서 1GB 안에서 잘 조절해주나요? | ❌ 아니요. 기본 설정이면 메모리 폭주 위험 있음 |
그럼 꼭 설정을 해줘야 하나요? | ✅ 네. -Xmx, -Xms는 운영 환경에서는 필수입니다 |
1GB로 안정적으로 돌릴 수 있는 방법은? | -Xmx256m 등으로 JVM 메모리 제한 + Redis 사용하지 않음 + EC2 스왑 추가 |
필요하시면 EC2 인스턴스 상황에 맞는 실행 스크립트 예제도 만들어 드릴 수 있어요.
배포 자동화까지 고려 중이시면 systemd나 Docker 기반으로도 도와드릴 수 있고요.
'인프라' 카테고리의 다른 글
[인프라] IT 인프라란? (0) | 2019.10.16 |
---|