개발을 하다 보면 헷갈리는 용어를 자주 마주하게 됩니다. 대표적인 예가 바로 로드 밸런서와 API 게이트웨이입니다. 이름만 보면 서로 전혀 다른 역할을 하는 것처럼 느껴집니다. 하지만 실제로 어떤 일을 하는지 떠올려 보면, 둘 다 "요청을 전달한다"는 공통점 때문에 비슷한 개념처럼 느껴지기도 합니다. 이러한 혼란은 개념을 충분히 분리해서 이해하지 못했을 때 자연스럽게 발생합니다. 이번 글에서는 로드 밸런서와 API 게이트웨이의 차이점과 공통점을 명확하게 정리해보겠습니다.그렇다면, 이 두 개념이 왜 혼동되는지 그 이유부터 살펴보겠습니다.두 기술 모두 클라이언트의 요청을 받아 다른 서버로 전달한다는 공통점을 가지고 있습니다.이 과정에서 "중간에서 요청을 처리한다"는 점 때문에 두 개념이 비슷하게 느껴질 수 ..
이전에 여러 객체를 프록시로 생성하거나, 프록시 객체를 활용하는 과정에서 Java는 자연스럽게 리플렉션(Reflection)이라는 기술을 사용하게 됩니다. 문제 발견: LazyConnectionDataSourceProxy 톺아보기read-only일때 replica 사용하게 하기master-slave 구조 이해하기DB에서 master-slave 형태로 변경하다는 뜻은 읽기 전용과 쓰기 전용을 분리한다는 의미입니다.최근에는 master-slave라는 용어보다는 primary-replb-programmer.tistory.com 분명... slow쿼리를 모니터링하려고 했는데... 어째서...return wrapPreparedStatement(preparedStatement, sql); 슬로쿼리 모니터링 인터페..
EDA 패턴을 적용해보자.(feat.kafka)이전 포스트에서 이어져서 진행이 되어집니다. 선착순 쿠폰 발급기 개발당신의 동시성 테스트가 원하는 결과가 나오지 않는 이유TL;DR: 낙관락과 비관락을 고르는 기준에 대해 설명합니다.배경b-programmer.tistory.com마지막 글에 간단하게 outbox패턴을 얘기하면서 카프카의 설정을 살짝 언급한 적이 있습니다. 사실 outbox패턴이 없어도 카프카는 메시지를 다시 읽을 수 있었습니다. 바로 @RetryalbeTopic이라는 어노테이션을 이용하면 producer에서 발송된 메시지를 다시 읽을 수 있게 유도할 수 있었습니다. 그렇다면, 이러한 설정들이 실제로 어떻게 동작을 할까요? 마지막에도 언급했듯이 제 목표는 native 하게 kafka를 사용하는..
이전 포스트에서 이어져서 진행이 되어집니다. 선착순 쿠폰 발급기 개발당신의 동시성 테스트가 원하는 결과가 나오지 않는 이유TL;DR: 낙관락과 비관락을 고르는 기준에 대해 설명합니다.배경그 전에도 낙관락, 비관락을 해봤기때문에 금방할 줄 알았다.하지만 아니b-programmer.tistory.com초기 구현에서는 쿠폰 재고를 DB에서 직접 관리했습니다. 발급 요청이 들어오면 트랜잭션 안에서 재고를 확인하고 차감하는 구조였기 때문에, 정합성 측면에서는 비교적 안전했습니다. 실제로 초과 발급도 발생하지 않았습니다. 하지만 대량 트래픽 환경에서는 다른 문제가 드러났습니다. 특정 쿠폰에 요청이 집중되자 동일한 재고 데이터에 대한 동시 접근이 늘어났고, 결국 DB 락 경합이 병목으로 이어졌습니다.즉, 정합성은 확..
당신의 동시성 테스트가 원하는 결과가 나오지 않는 이유TL;DR: 낙관락과 비관락을 고르는 기준에 대해 설명합니다.배경그 전에도 낙관락, 비관락을 해봤기때문에 금방할 줄 알았다.하지만 아니었다. 어디서 부터 문제 였을까?생각하기에는 비관락을 사b-programmer.tistory.com그때는 낙관락과 비관락에 대해서만 집중해서 테스트를 진행했던 거 같다.이번에는 차근차근 진행해 볼 예정이다. 낙관락도 비관락도 무엇인지 정확하게 알았으니 다른 테스트도 해도 크게 문제 될 건 없을 거 같다.일단 쿠폰을 한 장 준비해 둡니다. 이 쿠폰은 100장 제한이 걸려있으며, 불특정 한 사람들이 이 쿠폰 이용이 가능합니다.먼저 k6 스크립트를 준비해 주고 테스트를 진행해 봅니다.락을 걸기 전에현재 선착순 쿠폰을 구하는 ..
분산락을 적용한 뒤 부하 테스트를 진행하는 과정에서 5XX 응답이 과도하게 발생하는 현상을 확인했습니다. 이번 작업의 목적은 동일한 결제 성공 콜백이 동시에 들어오는 상황에서 분산락이 의도한 대로 동작하는지 검증하고, 그 결과를 해석 가능하게 만드는 것이었습니다. 문제는 5XX가 발생했을 때 그것이 분산락 경합에 의한 결과인지, 아니면 락 외부의 예외인지 구분하기 어려웠다는 점이었습니다. 따라서 이번 작업에서는 결제 기능 전체의 안정성 개선보다, 분산락 동작을 방해하는 노이즈를 줄이고, 락 경쟁 결과를 명확히 관측할 수 있도록 만드는 것에 초점을 맞췄습니다.먼저 200UV를 기준으로 잡고 k6를 돌려보겠습니다.30분간 200UV를 돌린결과 5XX에러가 19950번이 발생이 되었다는 것을 알 수 있습니다...
Stateless하게 개발한다는 것은 무엇을 의미할까? HTTP는 무상태(stateless)라고 하고, 아키텍처에서도 stateless라는 말이 자주 등장한다. 처음에는 이 개념이 잘 이해되지 않았다. 왜냐하면 상태를 가진다는 것은 결국 어딘가에 데이터가 저장된다는 의미이기 때문이다. 그렇다면 DB나 Redis 같은 저장소를 사용하는 순간 stateless하지 않은 것이 아닌가라는 생각이 들었다. 하지만 이는 잘못된 이해였다. Stateless의 기준은 인프라 전체가 아니라 서버이다. DB나 Redis를 사용하는 것은 상태를 없애는 것이 아니라, 서버 외부로 분리하는 것이다. 즉, stateless하게 개발한다는 것은 서버가 데이터를 전혀 저장하지 않는다는 의미가 아니라, 서버가 이전 요청의 상태를 기억..
스프링 이벤트스프링 이벤트(Spring Events)는 애플리케이션 내에서 컴포넌트 간의 느슨한 결합(loose coupling)을 유지하면서 비동기적 또는 동기적으로 메시지를 전달하는 메커니즘입니다.스프링의 Observer 패턴 기b-programmer.tistory.com이전에 스프링 이벤트를 학습한 적이 있습니다. 당시에는 이벤트가 어떻게 전달되고 실행되는지, 즉 내부 동작 방식에 집중해서 이해하려고 했습니다. 이번에는 조금 다른 관점에서 스프링 이벤트를 다시 바라보려고 합니다. 스프링 이벤트는 이벤트를 발행하는 퍼블리셔와 이를 처리하는 리스너로 구성되어 있으며, 이러한 구조는 메시지를 주고받는 MQ와 유사한 형태를 가지고 있습니다. 다만 스프링 이벤트는 Kafka나 RabbitMQ와 같은 외부 메..
이전에 데드락 관련 질문을 한적이 있었습니다. 그 당시 락을 학습을 했었을 때였던걸로 기억합니다. 아무튼 어떤 질문을 했었는데 그거는 데드락이 아니고 라이브락이라는 답변을 받은 적이 있습니다. 지금 이것들이 무엇인지 어떤건지 답변하기 어려워 이번 챕터를 준비를 하였습니다. 라이브락과 데드락의 차이는 무엇일까요? 데드락 (Deadlock)Deadlock은 두 단어로 이루어져 있습니다.Dead : 죽은, 멈춘Lock : 잠금, 자물쇠이를 직역하면 "죽은 잠금", 혹은 "완전히 막혀버린 상태"라는 의미가 됩니다.여기서 중요한 것은 Dead입니다. 단순히 잠겨 있는 상태가 아니라 더 이상 아무것도 진행되지 않는 상태를 의미합니다.가장 유명한 예시가 식사하는 철학자 문제입니다. 여러 명의 철학자가 원형 테이블에 ..
read-only일때 replica 사용하게 하기master-slave 구조 이해하기DB에서 master-slave 형태로 변경하다는 뜻은 읽기 전용과 쓰기 전용을 분리한다는 의미입니다.최근에는 master-slave라는 용어보다는 primary-replica라는 용어로 더 많이 사용이b-programmer.tistory.comMaster-Slave 환경을 구성하던 중 이상한 현상을 발견했습니다. 정상적인 구조라면 @Transactional(readOnly = true) 상황에서는Primary가 아니라 Replica로 라우팅되어야 합니다. 하지만 테스트를 진행해보니 예상과 다르게 ReadOnly 트랜잭션에서도 Primary가 사용되는 상황이 발생했습니다. 코드를 잘못 작성한 것일까 여러 부분을 확인해보았..
Actuatork6를 통해 부하 테스트와 API 테스트를 진행하면서 한 가지 한계를 느꼈습니다.요청을 보내고 결과를 확인하는 것은 가능했지만, 실제로 부하가 걸리는 동안 애플리케이션 내부에서 어떤 변화가b-programmer.tistory.com이전 장에서 Actuator에 대해 학습해봤습니다. Actuator는 Spring Boot 애플리케이션의 상태 정보를 확인할 수 있도록 제공되는 기능이라는 것을 알 수 있었습니다. Actuator를 통해 애플리케이션의 상태뿐만 아니라 메트릭 정보도 확인할 수 있으며, Prometheus와 같은 모니터링 시스템과 연동할 수 있는 endpoint도 제공됩니다. 또한 기본적으로 제공되는 다양한 메트릭 정보를 확인할 수 있다는 점도 알 수 있었습니다.그렇다면 기본적으로 ..