![[Springboot] 액추에이터(Actuator)](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdaIbMP%2FbtsGFA0BGhB%2FNC0epER6KKOwAG4XINsK61%2Fimg.png)
실무 모니터링 환경을 구축하기 위한 첫 번째 단계로 스프링부트에서 제공되는 액추에이터에 대해 학습한 내용을 정리하였습니다.
개요
운영 환경에서 서비스할 때 필요한 기능들을 프로덕션 준비 기능이라 합니다.
간단하게 알아보면 애플리케이션이 현재 살아있는지, 로그 정보는 정상 설정 되었는지, 커넥션 풀은 얼마나 사용되고 있는지 등을 확인할 수 있어야 합니다.
스프링부트에서 제공하는 액추에이터는 위와 같은 기능을 매우 편리하게 사용할 수 있는 다양한 편의 기능들을 제공합니다.
액추에이터
build.gradle 추가
//actuator 추가
implementation 'org.springframework.boot:spring-boot-starter-actuator'
의존성을 추가 후 아래 url로 접속해보면 몇 가지 기능을 볼 수 있습니다.
http://localhost:8080/actuator
엔드포인트 설정
액추에이터가 제공하는 기능 하나하나를 엔드포인트라 합니다.
각각의 엔드포인트는 /actuator/{엔드포인트명}과 같은 형식으로 접근 가능합니다.
엔드포인트를 사용하려면 다음 2가지 과정이 필요합니다.
- 엔드포인트 활성화 : 해당 기능을 사용할지 말지 선택
- 엔드포인트 노출 : 노출 위치 설정 (HTTP, JMX)
기본적으로 shutdown을 제외하면 대부분 기본으로 활성화 상태입니다.
엔드포인트 노출의 경우 JMX는 잘 사용하지 않으므로 HTTP에 어떤 엔드포인트를 노출할지 선택하면 됩니다.
application.yml : 모든 엔드포인트를 웹에 노출
management:
endpoints:
web:
exposure:
include: "*"
exclude: "env, beans"
shutdown 엔드포인트는 활성화가 안되어 있기에 웹에 노출도 되지 않습니다.
include의 경우 노출, exclude의 경우 제외 옵션입니다.
application.yml : 특정 엔드포인트 활성화
management:
endpoint:
shutdown:
enabled: true
다양한 엔드포인트
다양한 엔드포인트를 활용하여 애플리케이션 내부의 수 많은 기능을 관리하고 모니터링을 할 수 있습니다.
엔드포인트 목록
- bean : 스프링 컨테이너에 등록된 스프링 빈을 보여준다.
- conditions : condition 을 통해서 빈을 등록할 때 평가 조건과 일치하거나 일치하지 않는 이유를 표시한다.
- configprops : @ConfigurationProperties 를 보여준다.
- env : Environment 정보를 보여준다.
- health : 애플리케이션 헬스 정보를 보여준다.
- httpexchanges : HTTP 호출 응답 정보를 보여준다. HttpExchangeRepository 를 구현한 빈을 별 도로 등록해야 한다.
- info : 애플리케이션 정보를 보여준다.
- loggers : 애플리케이션 로거 설정을 보여주고 변경도 할 수 있다.
- metrics : 애플리케이션의 메트릭 정보를 보여준다.
- mappings : @RequestMapping 정보를 보여준다.
- threaddump : 쓰레드 덤프를 실행해서 보여준다.
- shutdown : 애플리케이션을 종료한다. 이 기능은 기본으로 비활성화 되어 있다
아래는 엔드포인트에 관한 공식문서 링크입니다.
Production-ready Features
You can enable recording of HTTP exchanges by providing a bean of type HttpExchangeRepository in your application’s configuration. For convenience, Spring Boot offers InMemoryHttpExchangeRepository, which, by default, stores the last 100 request-response
docs.spring.io
application.yml : 엔드포인트 경로 변경
management:
endpoints:
web:
base-path: "/myendpoint"
위와 같이 설정할 경우 /actuator/{엔드포인트} 대신 /myendpoint/{엔드포인트}로 변경됩니다.
실시간 로그 레벨 변경
개발 서버는 보통 DEBUG 로그를 사용하지만, 운영 서버는 보통 요청이 아주 많습니다.
그래서 운영 서버는 보통 INFO 로그 레벨을 사용합니다.
서비스 운영 중 문제가 발생하여 급하게 DEBUG나 TRACE 로그를 남겨서 확인해야 할 경우 일반적으로 로깅 설정을 변경하고, 서버를 다시 시작해야 합니다.
하지만 loggers 엔드포인트를 사용하면 애플리케이션을 다시 시작하지 않고, 실시간으로 로그 레벨을 변경할 수 있습니다.
POSTMAN 요청을 통해 실시간 로그를 변경해봅니다.
GET 요청을 통해 configuredLevel을 확인하면 변경된걸 확인할 수 있습니다.
액추에이터와 보안
보안적인 이슈
액추에이터는 URL을 통해 애플리케이션의 내부 정보를 많이 노출하게 됩니다.
그래서 외부로 공개된 곳에 액추에이터의 엔드포인트를 공개하는 것은 보안상 좋은 방법이 아닙니다.
대처방안으로는 액추에이터의 엔드포인트들은 외부로부터의 접근을 막고, 내부에서만 접근 가능하도록 설계할 수 있습니다.
액추에이터를 다른 포트에서 실행
예로 WAS의 포트는 8080으로 열되, 액추에이터의 포트는 외부에서 접근하지 못하는 포트로 설정할 수 있습니다.
application.yml : 액추에이터 포트 설정
management:
server:
port: 9292
만약 포트를 분리하기 어려운 경우 /actuator 경로에 인증 설정을 하는 것으로 외부 접근을 막는 방법을 생각할 수 도 있습니다.
하지만 추가적인 개발이 필요하므로 추천하지 않는 방법입니다.
만약 도커환경에서의 리버스 프록시를 사용하고 있다면?
만약 was가 도커 컨테이너로 실행이 되고 있고, 앞단에 Nginx를 통해 리버스프록시를 하고 있다고 가정해봅니다.
이럴 경우 액추에이터의 포트를 변경하여 서로다른 포트를 통해 접근을 할 수 있게 하는 방법에 대해 생각을해보면 다음과 같이 생각할 수 있습니다.
Nginx 설정 : 새로운 Location Block 추가
Nginx.conf 에서 location 블록을 액추에이터 경로에 맞게 추가함으로써 해당 포트로의 접근을 열 수 있습니다.
config 파일
server {
listen 443 ssl;
server_name your_server_name.com;
location /actuator {
proxy_pass <http://localhost:9092>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# 기타 설정...
}
또한 보안을 강화하기 위해 추가적인 조치를 할 수 있습니다.
예를 들어, IP주소 기반 접근 제한을 Nginx 설정에 추가하여, 허가된 사용자만이 액추에이터 엔드포인트에 접근할 수 있도록 할 수 있습니다.
config 파일
location /actuator {
proxy_pass <http://localhost:9092>;
allow 192.168.1.1; # 허용할 IP 주소
deny all; # 모든 다른 접근을 거부
# 기본 인증 설정...
}
정리
이번 프로젝트에서 실 서비스 운영을 위한 준비로 모니터링 환경을 구축하게 될 일이 생겨 모니터링 방법 및 스프링부트에서 제공되는 액추에이터에 대한 공부를 진행했습니다.
참고 강의로는 인프런 김영한님의 스프링 부트 - 핵심 원리와 활용을 통해 공부 및 정리를 했습니다.
추가적으로 제 서비스 환경에 맞추어 도커, Nginx를 사용하고 있을 경우 액추에이터의 보안적인 이슈를 어떻게 잡을지에 대한 추가적인 고민을 하는 시간은 매우 흥미롭고 재밌었습니다.
혹여나 다른 좋은 방법이 있다면 댓글로 남겨주시면 정말 감사하겠습니다.
이번 프로젝트에서 맡은 업무를 통해 단순히 기능 개발을 마무리하는것이 아닌 장애 대응을 위한 모니터링까지, 많은 것을 생각하며 개발할 수 있는 경험을 해봄으로써 서비스 운영 측면에서의 사고도 확장할 수 있도록 열심히 해봐야 할 것 같네요!
'Develop > SpringBoot' 카테고리의 다른 글
[JPA] 인스타그램 유저 검색 N+1 문제 (0) | 2024.04.02 |
---|---|
[JWT] 동작 원리 (Feat. Refresh Token) (0) | 2024.03.11 |
[JWT] JSON Web Token - With JWT.io (0) | 2024.03.11 |
세션(Session) & 쿠키(Cookie) (0) | 2024.02.23 |
[Swagger] 스프링 3.x Swagger 적용(With. SpringDocs) (1) | 2024.01.31 |
개발 기술 블로그, Dev
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!