분류 전체보기
-
Tomcat 에서 발생하는 간헐적 404 해결기Spring Framework 2026. 1. 25. 00:55
개요Spring Boot embedded-tomcat 환경의 특정 서버에서 404 응답이 발생하였습니다.해당 원인을 분석해서 해결한 내용을 공유해보고자 합니다. 현상A -> B 서버로 동일한 http 요청에도 불구하고 6건 중 5건은 성공하고 1건이 실패하였습니다.실패했을 때의 응답은 아래와 같습니다. HTTP Status 404 – Not Found 이를 404.html 파일로 만들어서 웹에서 확인하면 아래와 같은 화면을 만날 수 있습니다. 유효하지 않은 url으로 접근했을 때 나타나는 Whitelabel 페이지과 차이가 보입니다.분석위의 404 페이지를 생성하는 클래스는 org.apache.catalina.valves.ErrorReportValve 입니다.이는 Tomcat의 클래스이며..
-
Apache Tomcat ErrorReportValve에 logOnError 옵션 추가하기Spring Framework 2026. 1. 21. 22:13
개요Apache Tomcat의 ErrorReportValve는 HTTP 에러 발생 시 사용자에게 에러 페이지를 보여주는 역할을 합니다. 하지만 에러가 발생했을 때 이를 로그로 남겨 빠르게 인지할 수 있는 기능은 제공하지 않았습니다. 이로 인해 Tomcat 처리 단계에서 발생한 에러는 운영 환경에서 쉽게 놓치기 쉬웠고, 이를 개선하기 위해 에러 로그를 남길 수 있는 옵션을 추가하는 PR을 작성하게 되었습니다. Spring Boot + Tomcat 처리 흐름Spring Boot + Tomcat 환경에서 하나의 HTTP 요청은 보통 다음 순서로 처리됩니다.Client → Tomcat → Filter → DispatcherServlet → Controller 여기서 DispatcherServlet이 요청을 받..
-
Mongodb 쿼리 성능 개선하기 - 인덱스 추가프로젝트/mongoDB 2025. 9. 28. 21:48
개요서비스를 운영하던 중 배치 서비스가 유독 느리게 수행되는 현상을 발견하게 되었습니다.문제의 원인을 분석하고 쿼리 성능을 개선하기 위해 인덱스를 적용했던 사례를 기록해보고자 합니다. 문제 정의배치는 특정일자 전 데이터를 읽고, 해당 데이터가 특정 기간보다 오래되었다면 삭제하는 역할을 수행합니다.로그상 쿼리를 불러오고 삭제할 때 10초 정도의 시간이 소요되었음을 확인하여 해당 쿼리가 인덱스를 적절하게 활용하고 있지 않아서 데이터를 읽는 과정에서 느릴 것이라고 판단했습니다. 쿼리 파악해당 쿼리는 requtestAt 기준으로 특정 날짜 이전의 데이터를 가져오고, type column으로 한번 더 equals 연산을 하여 데이터를 가져오고 있었습니다. 그리고 정렬은 수행하지 않은 채로 100개의 데이터를 페이..
-
개발환경의 파티션은 어떤 consumer가 점유했을까?프로젝트/kafka 2025. 6. 30. 01:10
개요만약 kafka의 파티션이 3개이고, consumer가 1개라면 어떤 consumer가 파티션을 점유할까요? 만약 kafka의 파티션이 3개이고, consumer가 2개(로컬환경, 개발환경)라면 어떤 consumer가 파티션을 점유할까요? 추가로 concurrency 옵션은 어떤 관계가 있을까요? 위 질문에 답을 알아가는 과정을 통하여 예측가능한 테스트 환경을 만들 수 있습니다. Kafka Topic과 Partition Kafka는 이벤트의 관심사에 따라 각각 topic에 메시지를 적재합니다. foo라는 topic이 구성되어 있고 3개의 파티션으로 구성되어 있습니다. 이 파티션에는 kafka consumer가 붙어서 메시지를 처리합니다. 위 구조 덕분에 consumer의 처리량을 늘리고 싶다면 파티션..
-
NoSuchFieldError 원인 - gradle dependencies 문제 파악하기카테고리 없음 2025. 6. 8. 13:18
개요라이브러리 버전 업그레이드를 진행하던 중 NoSuchFieldError 예외가 발생했습니다. 이 글에서는 NoSuchFieldError가 어떤 상황에서 발생하는지, 실제 발생 사례를 바탕으로 원인 분석 및 해결 과정을 정리해보았습니다. ✅ NoSuchFieldError란?NoSuchFieldError는 Java 애플리케이션 실행 중 특정 클래스에서 존재하지 않는 필드에 접근할 때 발생하는 런타임 에러입니다. 컴파일 시점에는 정상적으로 컴파일되었지만, 런타임 시점에 클래스 간 버전이 맞지 않아 필드가 존재하지 않는 경우 주로 발생합니다.예를 들어, 어떤 라이브러리의 enum 클래스에 필드가 추가되었지만, 실제 실행 시에는 해당 필드가 없는 구버전의 enum이 로드될 경우 이 에러가 발생할 수 있습니다..
-
Kotlin coroutine graceful shutdown in spring bootSpring Framework 2025. 4. 6. 13:31
graceful shutdowngraceful shutdown은 애플리케이션이 종료될 때, 현재 진행 중인 작업을 완료한 후 종료하는 것을 말합니다. couroutine과 graceful shutdown@Componentclass CoroutineGracefulShutdown() : ApplicationRunner { override fun run(args: ApplicationArguments) { runBlocking { launch(Dispatchers.IO) { logger.info { "start" } sleep(30000) // 30초 기다림 logger.info..
-
humongous object javaJava/자바를 더 깊게 2025. 3. 15. 19:43
humongous object 란?humongous는 거대한 이라는 사전적 의미를 가지고 있습니다.humongous object는 이 글에서는 앞으로 거대한 객체로 칭하겠습니다. 하지만 거대하다는 것을 추상적인 의미를 가집니다.누군가는 1KB 정도의 객체를 거대하다고 생각할 수 있고, 누군가는 1MB 정도가 거대하다고 생각할 수 있습니다. JVM 세상에서 거대한 객체로 인식되는 것은 GC와 연관 있기 때문에 GC에 대해서도 알아보겠습니다. JVM GC - G1GCJDK 11부터는 default GC가 G1GC입니다.G1GC의 경우 Heap이 동일한 크기의 여러 지역으로 분할되어 있는 것이 특징입니다.각 지역은 Eden, Survior, Tenured로 분류되며 새로운 객체가 생성되면 Eden으로 할당됩니..
-
Long Transaction을 감지하고 대응하는 방법JPA 2025. 2. 25. 01:04
개요Long Transaction으로 인해 DB에 부하가 발생하여 같은 DB를 활용하는 모든 서버들에 영향이 가는 상황이 발생하여 왜 그런 일이 일어나는지, 어떻게 하면 예방할 수 있을지 공부하며 기록해보고자 합니다. Long Transaction이란?Long Transaction은 트랜잭션이 열리고 긴 시간 동안 commit, rollback이 수행되지 않고 있는 데이터베이스 트랜잭션을 말합니다. 데이터베이스에서 트랜잭션은 하나의 논리적인 작업 단위를 의미하며, 데이터의 일관성(Consistency)과 무결성(Integrity) 을 보장하는 중요한 역할을 합니다. 긴 시간이라는 것은 상대적이긴 개념입니다. 만약 평균 트랜잭션이 100ms 이내에 처리된다면, 1초만 넘어가도 상대적으로 Long Tran..