운영형 Spring
1. 운영형 Spring
1) 운영 가능
- 개발이 완료된 상태 + 운영이 가능한 상태로 만드는 것
- 로그로 원인 추적 가능
- 설정 분리로 환경별 대응
2) 운영형이 중요한 이유
- 새벽 3시 장애 발생 : 헬스체크 DOWN → 로그 확인 → 10분 내 원인 파악
- 스테이징 → 프로덕션 배포: 환경변수로 설정 주입 → 무사히 배포
2. 운영 3요소
| 요소 | 역할 | 질문 |
| 🩺 Health | 서버 상태 확인 | "앱이 살아있나?" |
| 📋 Log | 문제 원인 추적 | "왜 에러가 났나?" |
| ⚙️ Config | 환경별 설정 | "로컬 vs 운영 구분?" |
1) Health (헬스체크)
- 서버가 정상 동작 중인지 확인
- UP: 정상 / DOWN: 문제 발생
# 헬스체크 요청
curl http://localhost:8080/actuator/health
# 응답 예시
{"status":"UP"}
2) Log (로그)
- 장애 발생 시 원인 추적
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 연결 실패
3) Config (설정)
- 환경(로컬/개발/운영)별 다른 설정 적용
| 환경 | DB 호스트 | 로그 레벨 |
| local | localhost | DEBUG |
| prod | rds.amazonaws.com | INFO |
Spring Boot Actuator
1. 수동 헬스체크
1) 수동방식의 한계
- 기본 헬스체크는 동작하긴 하지만, DB 같은 의존성을 체크하려면 코드가 많이 필요
> 단순히 앱이 떠있다고 정상동작한다고 말할 수 없음 - 코드량 증가: 수동으로 하나하나 구현해주어야함
- 표준 없음: 프로젝트마다 응답 형식이 다름
- 유지보수 부담: 새 의존성 추가 시 헬스체크 코드도 수정
- 중복 코드: 모든 프로젝트에서 비슷한 코드 반복
2. Spring Boot Actuator
1) 개념
- 앱의 "운영 계기판"
- 앱의 상태, 메트릭, 환경 정보를 HTTP 엔드포인트로 제공
- 의존성을 추가하면 /actuator/health, /actuator/info 같은 엔드포인트가 자동으로 생성
2) Actuator 도입
- 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-actuator'
3) DB 자동 감지 실습
- 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.mysql:mysql-connector-j'
- /actuator/health 호출: DB가 있으면 Actuator가 알아서 체크
- 자동 감지되는 요소들

3. Actuator 주요 엔드포인트
1) 엔드포인트 목록

2) 노출 범위
management.endpoints.web.exposure.include=health,info
management.info.env.enabled=true
# info 호출 시 나오는 정보
info.app.name=health-app
info.app.version=1.0.0
3) /actuator/health 상세
- 상태 종류

- 기본 응답
{"status": "UP"}
- 상세 응답: application.yml에서 활성화
# never는 상세 정보 숨김
management.endpoint.health.show-details=always
- 응답 예시
{
"status": "UP",
"components": {
"db": {
"details": {
"database": "MySQL",
"validationQuery": "isValid()"
},
"status": "UP"
},
"diskSpace": {
"status": "UP",
"details": {
"total": 499963174912,
"free": 123456789012,
"threshold": 10485760
}
}
}
}
4) Actuator 보안
- 위험한 상황: /actuator/env 노출
management.endpoints.web.exposure.include=health,info,env
management.endpoint.env.show-values=ALWAYS
운영 로그 전략
1. 로그 레벨


- application.yml
logging.level.root=INFO
2. Spring Boot에서 로그 출력
1) SLF4J 어노테이션
- Java 로깅을 위한 표준 인터페이스
- Lombok @Slf4j 사용
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
public class HealthController {
@GetMapping("/log")
public String health() {
log.info("헬스체크 요청"); // INFO 레벨
log.debug("상세 디버깅 정보"); // DEBUG 레벨
log.error("에러 발생"); // ERROR 레벨
return "OK";
}
}
2) 로그 메서드

3. 로그 확인
1) 환경별 로그 확인 방법
- 포그라운드는 터미널에 붙어서 실행되는 방식
- 백그라운드는 터미널과 독립적으로 실행되는 방식

2) EC2 환경
- 포그라운드 실행
# SSH 접속 후
java -jar app.jar
# → 로그가 터미널에 출력
# → SSH 끊으면 앱도 종료됨
- 백그라운드 실행 (nohup)
# 백그라운드 실행 (로그를 app.log 파일로 저장)
nohup java -jar app.jar > app.log 2>&1 &
# 로그 확인 (위에서 지정한 app.log 파일)
tail -f app.log # 실시간 로그
tail -100 app.log # 최근 100줄
cat app.log # 전체 로그
Profile별 설정 분리
1. Profile별 설정 분리 이유
1) 분리 이유
- 코드는 같고 설정만 다르게 하면 환경별 배포가 가능
- 환경별로 다른 예시

1) 올바른 환경별 설정 분리 방식
- 환경별 설정 분리
application.properties → 공통 설정
application-local.properties → 로컬 설정
application-prod.properties → 운영 설정 (비밀번호는 환경변수)
- 장점
- 코드 수정 없이 환경 변경
- 비밀번호는 환경변수로 안전하게
- 하나의 JAR로 모든 환경 대응
2. Spring Boot Profile별 설정
1) 파일명 규칙
- Spring Boot는 다음 규칙의 파일명을 보고 profile을 인식
application-{profile}.properties
- {profile} 자리에 들어가는 값이 profile 이름
2) application.properties의 역할
- 공통 설정 파일
- profile이 무엇이든 기본적으로 먼저 읽힘
3) 설정 우선순위
- profile 파일의 값이 우선 적용
- 공통 설정은 기본값
- profile 설정은 해당 환경에서 덮어쓰기
3. Profile 활성화 방법
1) 어떤 profile을 쓸지 정하는 방법
- Spring Boot는 실행할 때 어떤 profile을 사용할지 지정
- 핵심 설정
spring.profiles.active
- 예를 들어 prod를 활성화하면 application-prod.properties를 함께 읽음
2) Profile 활성화 우선순위
1. 프로그램 인자
2. 환경 변수
3. JVM 옵션
4. application.yml / application.properties
- 프로그램 인자: 실행 명령에 직접 넣는 방법
java -jar app.jar --spring.profiles.active=prod
- 환경 변수: OS나 서버에서 환경 변수로 설정하는 방법
export SPRING_PROFILES_ACTIVE=prod
java -jar app.jar
- JVM 옵션: 자바 실행 옵션으로 전달하는 방법
java -Dspring.profiles.active=prod -jar app.jar
- application.properties에 직접 지정: 공통 설정 파일에 기본값처럼 넣어둘 수 있음
spring.profiles.active=local
3) Profile별 설정 분리 실습
- application.properties (공통)
spring.application.name=camp-health-app
spring.profiles.active=local
server.port=8080
management.endpoints.web.exposure.include=health,info
- application-local.properties (로컬)
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=123456
management.endpoint.health.show-details=always
- application-prod.properties (운영)
spring.datasource.url=${DB_URL}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
management.endpoint.health.show-details=never # 운영에서는 숨김
4) 운영(prod)에서는 민감 정보를 환경변수로 주입
spring.datasource.url=${DB_URL}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
- 운영 DB 비밀번호를 application-prod.properties에 직접 넣어버리면 위험
AWS Parameter Store
1. AWS Parameter Store
1) 개념
- 설정값을 안전하게 저장하고 관리하는 서비스

2) 파라미터 생성


- 예시
spring.datasource.url=${DB_URL}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
3) Spring Cloud AWS 연동 (Parameter Store 값을 자동 가져오기)
- 의존성 추가
implementation 'io.awspring.cloud:spring-cloud-aws-starter-parameter-store:4.0.0-RC1'
- application-prod.properties 설정
spring.config.import=aws-parameterstore:/camp-health-app/prod/
spring.datasource.url=jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_NAME}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
2. EC2 - AWS Parameter Store 권한 설정
1) IAM 정책 생성
- EC2에서 Parameter Store를 읽으려면 IAM 권한이 필요
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:GetParameter",
"ssm:GetParameters",
"ssm:GetParametersByPath"
],
"Resource": "arn:aws:ssm:ap-northeast-2:*:parameter/app/*"
}
]
}'🔌 SPARTA > Courses' 카테고리의 다른 글
| [클라우드 기반 백엔드 설계] 클라우드와 AWS 기초 (0) | 2026.03.10 |
|---|---|
| 스탠다드반 10회차: Filters & Proxy Objects (0) | 2026.03.09 |
| 스탠다드반 9회차: TDD와 단위 테스트 (0) | 2026.03.05 |
| 스탠다드반 8회차 : 로깅(AOP)와 인증/인가의 시작(JWT) (0) | 2026.03.04 |
| Spring Security와 SecurityContext (0) | 2026.03.03 |