🛠️ 개발 환경Java: 21Spring Boot: 3.4.4DB: RDS + MariaDB💬 상황 설명최근 합류한 회사는 개발 조직이 최근에 만들어진 곳이었다. 빠르게 서비스를 만들다 보니 인프라에 부족한 부분이 많았다. 그래서 가장 먼저 손을 댄 일은 에러 알림을 슬랙으로 보내는 것이었다. 그 동안 아무도 몰랐던 에러들이 하나씩 수면 위로 올라왔고, 하나씩 정상화를 진행했다. 알림 체계를 갖추고 얼마 지나지 않아 순식간에 엄청 많은 에러 메세지가 쏟아졌다. 사이트를 확인해보니 동작은 하지만 정말 느렸고, 로그를 확인해보니 커넥션 풀 고갈이 문제였다. 하지만 실제 원인을 분석해본 결과 커넥션 풀 고갈은 표면적인 문제였다.웹 훅이 사용하는 커넥션 풀을 지정하지 않았다.순식간에 많은 웹 훅이 쏟아지면서..
🛠️ 개발 환경Kotlin : 1.9.25Spring boot : 3.3.4Github왜 Elasticsearch를 사용할까?DB에서 특정 문자열이 포함된 데이터를 검색할 때 LIKE 연산을 사용하게 된다. 예를 들어, 5만 개의 편의점 상품이 있다고 생각해보자. 내가 '쫀득'을 검색하려면, product 테이블에서 LIKE '%쫀득%' 같은 조건으로 값을 찾게 된다. B-Tree 인덱스는 정렬된 키를 바탕으로 '어디부터 어디까지'라는 범위를 빠르게 좁혀 탐색하는 구조이다. 때문에, LIKE '쫀득%'의 경우 인덱스를 탈 수 있지만, LIKE '%쫀득%'(leading wildcard) 는 문자열의 시작(prefix)이 고정되지 않기 때문에, 인덱스로 탐색 범위를 만들기가 어렵다. 결과적으로 옵티마이저..
🛠️ 개발 환경Kotlin: 2.2.0Spring Boot: 3.5.3💬 상황 설명회사에서는 WebFlux 기반의 서버를 사용하고 있어서, 컨트롤러 호출 전 Netty의 고수준에서 요청 데이터를 받아 내부 객체 형태로 변환한다. 이 과정에서 요청 본문을 UTF-8로 인코딩한 ByteArray로 저장한 뒤, 이를 문자열로 디코딩하여 누적(concatenate)하는 방식으로 처리한다. 대량의 데이터가 요청될 경우, Netty가 기본적으로 8KB(8192바이트) 단위로 청크로 나누어 수신하는데, 이때, 8KB 경계에서 UTF-8 멀티바이트 문자가 중간에 잘리면, 디코딩 과정에서 유효하지 않은 시퀀스로 간주되어 � (U+FFFD)로 표시된다. 이를 서로게이트 페어가 깨졌다고 표현한다. 예를 들어, 8KB(8..
🛠️ 개발 환경kotlin : 2.1.10Spring Boot : 3.3.10💬 상황 설명우선 현재 사용 중인 springdoc의 버전은 다음과 같다.implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0")코틀린 + 스프링 부트를 기반으로 API를 개발하면서, 다음과 같은 형태로 API의 request/response 클래스를 설계했다.object ApiPostProductBacklog { const val PATH = "/api/v1/product-backlog" data class Request( val title: String, val description: String, ..
🛠️ 개발 환경kotlin : 2.1.0Spring Boot : 3.3.0💬 상황 설명현재 재직 중인 회사는 여러 도메인 엔티티를 하나로 묶어 관리하는 에그리게이트(Aggregate) 단위로 모듈이 나누어져있고, 각 에그리게이트 내부에 있는 엔티티 기반의 API를 개발한다. 한 페이지에서 여러 엔티티에 대한 정보가 필요할 경우, 프론트에서 각 API를 호출하여, 데이터를 뿌려준다. 하지만, 특정 뷰에서는 A 데이터를 기반으로 B 데이터를 합친 결과를 보여준다. 예를 들어, C에 대한 리스트를 보여주기 위해서는 A를 먼저 조회하고, A가 속한 B를 찾은 뒤, 결과를 합쳐서 C를 보여주는 것이다. B는 여러 개의 A를 가질 수 있기 때문에, 정규화에 의해 AB라는 중간 테이블을 두어 관리를 하고 있다. ..
🛠️ 개발 환경kotlin : 2.1.0Spring Boot : 3.3.0💬 상황 설명회사 프로젝트에서 서비스 로직을 개발하던 중, 서버를 실행하니 다음과 같은 에러 메시지가 발생했다.java.lang.NoSuchMethodError: 'java.lang.Object server.temperature.TemperatureService.findTemperature(int, kotlin.coroutines.Continuation)'@Serviceclass TemperatureService( ...) { suspend fun findTemperature( temperatureCatRowid: Int ): Flow = ...}에러 메시지에 보이는 것과 같이 NoSuchMehtod..