본문 바로가기

Kotlin6

분산 락이 서비스를 죽이고 있었다 - Redisson 경합을 1/1000로 줄인 Segment 블록 할당 패턴 분산 환경에서 ID 채번 API의 부하 테스트를 돌렸더니 실패율 91%가 나왔다. DB 쿼리는 2ms인데 응답은 5초. 원인은 Redisson 분산 락 경합이었고, Pod를 아무리 늘려도 소용없었다. 해결은 "락을 더 안전하게 만드는 것"이 아니라 "락이 필요한 순간 자체를 줄이는 것"이었다. Segment 블록 할당 패턴으로 락 빈도를 1/1000로 줄이고, Valkey Sentinel Failover까지 견디는 구조를 만든 과정을 기록한다.Redisson 분산 락 + DB SELECT FOR UPDATE 이중 락 구조에서, 50 VUs 부하 시 실패율 91%, 처리량 8.89 req/sPod별 1,000건 ID 블록을 사전 확보하고, 블록 내에서는 AtomicInteger로 무락 채번하는 Segmen.. 2026. 4. 13.
4코어 4GB 러너 서버에서 Gradle 빌드 시간 86% 줄이기 벼르고 있었다시제품화 마감이 코앞이다.프로젝트 막바지에 접어들면서 코드량과 PR 양이 급격하게 늘었다. AI 코딩 도구를 적극적으로 활용하면서 개발 속도 자체는 나름 빨라졌는데, 그 속도를 인프라가 못 받쳐주고 있었다. PR이 쏟아지는데 빌드/테스트 파이프라인이 병목이 되어 리뷰와 머지가 밀리기 시작했다.팀원들 사이에서 "PR 확인이 너무 오래 걸린다"는 말이 나왔다. 솔직히 말하면, 그 원인이 전부 CI 속도 때문만은 아니었다. AI 도구를 아직 제대로 활용하지 못하는 경우도 있었고, 코드 리뷰 시 맥락을 빠르게 짚지 못해서 시간이 걸리는 경우도 있었다. 하지만 그건 기술적으로 풀 수 있는 문제가 아니다. 사람의 사고 속도나 도구 숙련도는 강제할 수 없다.그래서 방향을 잡았다. 기술적으로 풀 수 있는 .. 2026. 3. 19.
Kotlin + Spring Boot: 비동기 멀티홉 환경에서 예외를 유실하지 않는 전략 마이크로서비스 아키텍처(MSA) 확산에 따라, 하나의 요청을 처리하기 위해 내부적으로 다수의 외부 API를 호출하는 '멀티홉(Multi-hop)' 구조가 보편화되었다. 성능 최적화를 위해 CompletableFuture나 @Async를 활용한 비동기 호출을 도입하지만, 이때 발생하는 가장 큰 문제는 비동기 스레드에서 발생한 예외가 호출자에게 전달되지 않고 소멸한다는 점이다.이펙티브 소프트웨어 설계 3장의 원칙을 바탕으로, Kotlin + Spring Boot 환경에서 비동기 예외를 안전하게 가로채고 처리하는 전략을 정리한다.1. 비동기 예외 처리가 어려운 이유전형적인 Spring MVC 환경에서는 요청을 처리하는 스레드와 예외가 발생하는 스레드가 일치한다. 따라서 @RestControllerAdvice는.. 2026. 3. 8.
Kotlin 제너릭 완전 정복: 클래스 vs 함수, 타입 추론까지 제너릭(Generic)은 "타입을 파라미터화한다"는 점에서 클래스와 함수 모두에 적용될 수 있다.하지만 클래스 단위로 제너릭을 정의하는 것과 함수 단위로 정의하는 것은 의도도 다르고 타입 추론 방식도 다르다.이번 글에서는 Kotlin 제너릭의 핵심 개념부터 실무에서 활용할 수 있는 고급 패턴까지, 실제 코드 예제와 함께 그 차이를 명확히 짚어본다.제너릭 클래스 — 상태(state)에 타입을 입힌다제너릭 클래스는 객체의 속성(필드) 이나 클래스 내부 메서드 전체가 특정 타입에 맞춰 동작하도록 만드는 패턴이다.class Box(private val content: T) {fun get(): T = content}이 클래스는 Box, Box 등으로 인스턴스화될 수 있다.val intBox = Box(123)v.. 2025. 10. 5.