| 구분 | 개발 완료 | 운영 가능 |
|---|---|---|
| 정의 | 기능이 동작함 | 배포 후에도 관리 가능 |
| 상태 확인 | ❌ "돌아가는 것 같다" | ✅ 헬스체크로 확인 가능 |
| 장애 대응 | ❌ "왜 안 되지?" | ✅ 로그로 원인 추적 가능 |
| 환경 대응 | ❌ "내 PC에서는 됐는데" | ✅ 설정 분리로 환경별 대응 |
단순히 개발이 완료된 상태와 운영 가능한 상태는 다름!
최종 목표는 코드의 완성이 아니라, 운영이 가능한 상태로 만드는 것
Health, Log, Config
목적: 서버가 정상 동작 중인지 확인
# 헬스체크 요청
curl http://localhost:8080/actuator/health
# 응답 예시
{"status":"UP"}
목적: 장애 발생 시 원인 추적
2024-01-15 10:30:45 INFO - Application started
2024-01-15 10:31:02 ERROR - Database connection failed
2024-01-15 10:31:02 ERROR - java.sql.SQLException: Connection refused
로그를 보면 DB 연결 실패가 원인임을 알 수 있음
목적: 환경(로컬/개발/운영)별 다른 설정 적용
코드 수정 없이 환경 변수로 설정
Spring Boot Actuator는 앱의 상태, 메트릭, 환경 정보를 HTTP 엔드포인트로 제공하는 라이브러리. 의존성을 추가하면 /actuator/health, /actuator/info 같은 엔드포인트가 자동으로 생성됨
implementation 'org.springframework.boot:spring-boot-starter-actuator'
| 엔드포인트 | 용도 | 민감도 | 기본 노출 |
|---|---|---|---|
| /actuator/health | 앱 상태 확인 | 🟢 낮음 | ✅ |
| /actuator/info | 앱 정보 | 🟢 낮음 | ❌ |
| /actuator/metrics | 성능 지표 | 🟡 중간 | ❌ |
| /actuator/env | 환경변수, 설정값 | 🔴 높음 | ❌ |
| /actuator/configprops | 모든 설정값 | 🔴 높음 | ❌ |
| /actuator/heapdump | JVM 메모리 덤프 | 🔴 높음 | ❌ |
| /actuator/threaddump | 스레드 정보 | 🟡 중간 | ❌ |
로그 레벨(Log Level)은 로그의 심각도를 나타내는 분류. 개발 시에는 상세한 DEBUG 로그가 필요하지만, 운영 시에는 성능을 위해 INFO 이상만 출력함
| 로그 레벨 | 용도 | 예시 |
|---|---|---|
| ERROR | 에러, 예외 상황 | DB 연결 실패, NPE |
| WARN | 경고, 잠재적 문제 | 느린 쿼리, 재시도 발생 |
| INFO | 일반 정보 | 앱 시작, 요청 처리 완료 |
| DEBUG | 디버깅용 상세 정보 | 변수 값, SQL 쿼리 |
| TRACE | 매우 상세한 정보 | 메서드 진입/종료 |
Spring Boot에서는 SLF4J를 사용하여 로그를 출력함
-> @Slf4j
파일명: 활성화되는 profile
설정값을 안전하게 저장하고 관리하는 서비스
| 파라미터 이름 | Type | 용도 |
|---|---|---|
| /{app이름}/prod/DB_HOST | String | DB 엔드포인트 |
| /{app이름}/prod/DB_PORT | String | 3306 (MySQL port) |
| /{app이름}/prod/DB_NAME | String | 데이터베이스명 |
| /{app이름}/prod/DB_USERNAME | String | 사용자명 |
| /{app이름}/prod/DB_PASSWORD | String | 비밀번호 |


# 기본 형식
scp -i <키페어경로> <로컬파일> <사용자>@<EC2-IP>:~/app.jar
# 예시
scp -i ~/.ssh/my-key.pem app.jar ec2-user@{EC2-IP}:~/app.jar



-> 역할을 부여하니 잘 실행되는 모습




처음에는 Spring Boot Actuator, 로그 설정, 환경 설정 분리 같은 것들이 왜 필요한지 잘 이해되지 않았다.
단순히 서버가 실행되고 API가 정상 동작하면 개발이 완료된 것이라고 생각했기 때문이다.
하지만 EC2에 직접 애플리케이션을 배포하고 실행 과정을 확인하면서
“개발 완료”와 “운영 가능한 상태”는 다르다는 것을 이해할 수 있었다.
처음에는 /actuator/health 같은 엔드포인트가 어디에 쓰이는지 감이 오지 않았다.
하지만 EC2에 배포한 후 직접 요청을 보내보면서 서버 상태를 확인할 수 있었다.
curl http://{EC2-IP}:8080/actuator/health
응답
{"status":"UP"}
이 결과를 통해 서버가 정상적으로 동작하고 있는지 외부에서 확인할 수 있다는 점을 이해했다.
즉 단순히 서버가 실행된 것이 아니라
서비스 상태를 확인할 수 있는 구조가 운영 환경에서는 중요하다는 것을 알게 되었다.
개발 단계에서는 로그를 크게 신경 쓰지 않았다.
하지만 운영 환경에서는 문제가 발생했을 때 로그가 원인을 파악할 수 있는 중요한 정보가 된다.
예를 들어 다음과 같은 로그가 있다면
ERROR - Database connection failed
java.sql.SQLException: Connection refused
단순히 "서버가 동작하지 않는다"가 아니라
DB 연결 문제라는 원인을 빠르게 파악할 수 있다.
그래서 운영 환경에서는 상황에 맞게 로그 레벨을 설정하는 것이 중요하다는 것도 이해할 수 있었다.
개발 환경과 운영 환경은 사용하는 설정이 다르다.
예를 들어
만약 이러한 설정이 코드에 하드코딩되어 있다면
환경이 바뀔 때마다 코드를 수정해야 하는 문제가 발생한다.
그래서
application-localapplication-devapplication-prod같이 Profile 기반 설정 분리를 사용하고
DB 계정이나 비밀번호 같은 민감한 값은 AWS Parameter Store를 통해 관리하는 방식이 필요하다는 것을 이해했다.
이번 실습을 통해 단순히 기능을 구현하는 것에서 끝나는 것이 아니라
이 세 가지가 있어야 실제로 운영 가능한 애플리케이션이 된다는 것을 이해할 수 있었다.