이번 포스팅에서는 성능 테스트와 시스템 운영 환경에서 어떤 지표를 주시해야 하는지, 그리고 Spring Boot 환경에서 Prometheus와 Grafana를 활용해 직접 모니터링 환경을 구축한 경험을 공유하고자 합니다.
빠른 응답 시간은 사용자 이탈률을 낮추고, 안정적인 시스템은 비즈니스 신뢰도를 높입니다. 그렇기 때문에 이러한 지표를 꾸준히 관찰하고 개선하는 것은 매우 중요하다고 생각합니다.
이전 포스팅이었던 “2편. Spring Boot 요청 흐름 추적: Logging Filter와 traceId 적용기”에 이어, 이번 글에서는 3편을 작성해보고자 합니다.
이 글은 경험을 바탕으로 한 하나의 접근법이며, 정답이라기보다는 여러분이 각자의 상황에 맞는 최적의 방법을 찾아가는 데 도움이 되기를 바라는 마음으로 작성했습니다.
성능 테스트나 Prometheus, Grafana에 대한 기본적인 개념을 알고 계신다면 이 글을 수월하게 읽으실 수 있을 겁니다.
이 글은 아래에 해당하는 분들께 도움이 될 것입니다.
성능 테스트 시 어떤 지표를 봐야 할지 막막하신 분
Prometheus가 수집하는 핵심 지표의 의미가 궁금하신 분
Spring Boot 애플리케이션의 지표를 Grafana 대시보드로 직접 만들어보고 싶으신 분
참고
: 본 글에서 소개되는 코드 예시는 현재 시점의 구현을 바탕으로 작성되었으며, 프로젝트가 발전함에 따라 내용이 변경되거나 개선될 수 있음을 미리 알려드립니다.이 글에서 다루는 모든 코드는 깃허브에서 확인하실 수 있습니다.
이번 포스팅에서는 개인적으로 진행한 쿠폰 발급 시스템 프로젝트에서 분산락(Distributed Lock) 메커니즘을 개선했던 경험을 공유하고자 합니다. 초기 시스템은 단일 Redis 서버 환경을 기준으로 SETNX
명령어를 직접 사용하여 분산락을 구현했습니다.
물론 SETNX
는 간단하게 분산락을 구현할 수 있는 방법이지만, 몇 가지 불편한 점과 단일 인스턴스 환경에서도 고려해야 할 점들이 있었습니다. 예를 들어, 락 획득 및 해제 로직이 비즈니스 코드와 섞여 가독성을 해치거나, 반복적인 try-finally
구문을 사용해야 하는 점, 그리고 락 임대 시간(Lease Time) 관리의 복잡성 등이 그것입니다.
본 글에서는 이러한 점들을 개선하기 위해 Redisson의 RLock
과 Spring AOP를 도입하여, 비즈니스 로직과 락킹 로직을 분리하고 보다 안정적이며 재사용 가능한 분산락 코드를 작성한 과정을 상세히 설명드리겠습니다. 현재는 Redis 단일 인스턴스 환경을 기준으로 설명하며, 고가용성 환경으로의 확장은 향후 과제로 남겨두었습니다.
이번 포스팅에서는 Spring Boot 프로젝트에서 HTTP 요청과 응답을 효과적으로 로깅하고,
멀티쓰레드 환경에서 요청 흐름을 명확히 추적할 수 있도록 traceId
를 활용하는 방법을 소개합니다.
일반적으로
requestId
로 요청을 구분하고,traceId
로 전체 요청 흐름을 추적합니다.이 글에서는 단일 서비스 환경을 다루지만, 초기부터 traceId
를 적용하여 향후 분산 시스템에서도 확장 가능한 구조를 제공합니다.
특히, 실무에 적용한 내용을 중심으로 프로덕션 환경에서도 활용 가능한 실용적인 예제를 설명합니다.
Spring Boot 프로젝트에 Logging Filter를 적용하고자 하는 분
Filter와 HandlerInterceptor의 차이점을 알고 싶은 분
OncePerRequestFilter의 동작 원리와 사용 이유가 궁금한 분
멀티쓰레드 환경에서 로그가 뒤섞이는 문제를 해결하고 싶은 분
프로덕션 환경에 바로 적용 가능한 실용적인 예제를 찾는 분
관련 포스팅
해당 섹션에 대한 자세한 내용은 이 글을 참고해 주시기 바랍니다.
아래 세부 섹션에 있는 내용은 해당 글과 다른 자료들을 종합해서 정리했습니다.
Filter
는 Spring Framework의 일부가 아닌 웹 서버(servlet container) 수준의 컴포넌트입니다.
요청과 응답을 서블릿이 처리하기 전후로 가로채어 조작할 수 있습니다.
대표적인 예로 Spring Security
가 있습니다.
Spring Security
에서는 인증/인가를 위해 여러 개의 Filter 체인을 사용하며, 이를 Spring과 연동하기 위해 DelegatingFilterProxy
를 활용합니다.
이 구조 덕분에 Spring Security
는 Spring MVC에 종속되지 않고도 동작할 수 있습니다.
Filter는 다음과 같은 메서드를 제공합니다.
init
: 필터 초기화 시 호출doFilter
: 요청과 응답을 가로채어 처리 (핵심 메서드)destroy
: 필터 종료 시 호출멀티 모듈 프로젝트로 전환하면서 환경별 로그 설정의 필요성을 절실히 느꼈습니다.
운영 환경에서는 로그의 형식과 수준이 서비스 안정성과 직결되기 때문에 더욱 중요합니다.
이번 글은 실제 운영 환경에서 적용하는 것 보다는 멀티 모듈 구조에서 환경별로 logback.xml
을 구성한 경험을 공유하기 위해 작성했습니다.
관련 포스팅
글또는 글 쓰는 개발자 모임의 줄임말입니다. 궁금하시다면 글또 운영진분들이 만든 홈페이지에 가보시면 자세히 확인할 수 있습니다.
지난 글또 9기 회고에 이어, 글또 10기가 3월 30일을 끝으로 마무리되면서 지난 6개월간의 활동을 돌아보고자 이 글을 작성하게 되었다.
글또 10기를 시작한 이유는 9기 때와 마찬가지로 글을 꾸준히 작성하는 것을 목표로 삼았고, 글쓰기 외에도 얻을 수 있는 다양한 장점들이 있어 다시 한번 참여하게 되었다.
이번 10기를 가로(INPUT/OUTPUT/못해서 아쉬운 것)과 세로(예상했던 일/예상에 없던 일)를 기준으로 표를 만들었고, 활동을 키워드로 정리해본 결과, 아래 그림과 같이 필자의 주요 활동들을 한눈에 확인할 수 있다.
(해당 회고 템플릿을 제공해준 YI님께 이 자리를 빌어 감사의 말씀 전합니다 👏)