안정적인 웹훅 수신부 구현 패턴
·
Pattern
들어가며입사 후 처음으로 외부 서비스의 웹훅을 받아 처리하는 기능을 맡았다. 처음엔 단순해 보였다."엔드포인트 하나 열고, 요청 받아서 DB에 저장하면 끝 아닌가?" 근데 막상 구현하다 보니 질문이 끝없이 나왔다.같은 이벤트가 두 번 오면 어떻게 되지?처리 중에 서버가 죽으면?웹훅 보안은 HMAC이라던데, 정작 연동할 서비스는 헤더에 키 하나만 주던데?웹훅 요청을 DB에 저장해야 하나, 그냥 로그면 되나?송신자가 timeout 났다고 재시도하면, 우리 시스템 멀쩡한데 중복 처리되는 거 아닌가?이리저리 알아보고 공부하며 알게 된 내용을 정리했다. 비록 정답은 아닐 수 있어도, 같은 고민을 하는 사람에게 조금이나마 도움이 됐으면 한다.1. 웹훅의 본질: 왜 어려운가웹훅을 한 줄로 정의하면 "송신자가 수신자에..
Transactional Outbox Pattern: 이벤트를 절대 잃지 않는 방법(부재: At-least-once)
·
Pattern
외부 API를 호출하거나 다른 모듈에 이벤트를 전달할 때, 이런 고민을 해본 적 있을 것이다.DB에는 저장됐는데 이벤트 전달이 실패하면 어떻게 하지? 반대로 이벤트는 나갔는데 DB가 롤백되면? Outbox 패턴은 이 두 가지 불안을 동시에 해결하는 방법이다.1. 왜 이 패턴이 필요한가우리가 흔히 작성하는 코드@Transactionalfun placeOrder(request: OrderRequest) { val order = orderRepository.save(Order(request)) // DB 저장 paymentGateway.charge(order) // 외부 결제 API 호출}코드 자체는 문제없어 보인다. 그런데 실제 운영 환경에서는 이런 상황이 ..
DB 락을 전략, 모드, 범위로 나누어 이해하기
·
Database
DB 락을 공부하다 보면 비관적 락, 낙관적 락, 공유 락, 배타 락, 레코드 락, 갭 락 같은 용어들이 한꺼번에 등장한다.처음에는 전부 “락”이라는 이름으로 묶여 있어서 헷갈리기 쉽다.그런데 이 용어들은 같은 기준으로 분류된 것이 아니다.크게 보면 다음 세 가지 관점으로 나누어 이해할 수 있다.동시성 제어 전략락 모드락 범위즉, 어떤 용어는 “어떻게 동시성을 제어할 것인가”에 대한 전략이고, 어떤 용어는 “어떤 강도의 락인가”에 대한 모드이며, 어떤 용어는 “어디에 락이 걸렸는가”에 대한 범위다.1. 동시성 제어 전략비관적 락비관적 락은 이름 그대로 충돌이 발생할 가능성을 비관적으로 보는 방식이다.즉, “다른 트랜잭션이 이 데이터를 건드리면 문제가 생길 수 있으니, 미리 잠가두자”는 전략이다.대표적인 ..
[Spring] 예제로 연습해본 동시성 문제 해결 과정 feat. 비관적 락 & 분산 락 & 이벤트 기반 처리
·
Spring
개요이전 포스팅에서는 분산 시스템 환경을 고려하지 않고, 단일 시스템에서의 락 관리 방법을 적용해보았다. 이번 시간에는 실제 인스턴스를 여러 개를 띄우진 않겠지만, 실제 DB도 연결한 후, 여러 인스턴스가 실행 중이라고 가정한 분산 시스템 환경에서 락을 관리하는 방법에 대해 알아보겠다!DB 및 Redis 연결간단하게 docker를 사용하여 MySQL을 실행한 후, JPA를 통해 이에 연결하도록 하겠다. 뒤에 분산 락 구현을 위해 Redis도 사용할 예정이니 미리 컨테이너로 실행해두겠다. build.gradledependencies { ... runtimeOnly 'com.mysql:mysql-connector-j' implementation 'org.springframework.boot:..
[Spring] 예제로 연습해본 동시성 문제 해결 과정 feat. ReentrantLock
·
Spring
개요과거 Java의 동시성 프로그래밍을 공부하고 포스팅까지 진행해보았고, 나름 개인 프로젝트를 진행하며 동시성 문제를 스스로 해결할 수 있는 능력이 있다고 생각했었지만, 항상 동시성 문제를 직면하게 될 때에는 머릿속에 물음표가 먼저 생겼던 것 같다. 그래서 이번 기회에 간단한 요구사항을 만족하는 시스템을 구현하여 다양한 방식으로 동시성 문제를 해결하는 연습을 해보려고 한다.거두절미하고 바로 시작하겠다. 이번에 구현할 시스템은 아주 간단한 은행 시스템이라고 가정하여 잔액 조회, 입금, 출금 로직만을 구현한다. 당연히 돈과 관련된 문제이니 동시성 문제가 발생해서는 안되니 이에 대한 처리도 해줄 것이고, 테스트 코드까지 작성해볼 예정이다.기본 기능 구현Account (도메인 모델)@Getter@NoArgsCo..
[컴퓨터 네트워크 수업] Chapter 3. Transport Layer 요약
·
Network
전송 계층의 개념 및 기본 기능전송 계층은 프로세스(애플리케이션) 간 통신을 담당전송 계층의 주요 기능 2가지Multiplexing / Demultiplexing신뢰성 있는 데이터 전송과 흐름/혼잡 제어Mutliplexing & DemultiplexingMutliplexing(다중화): 여러 앱이 데이터를 보낼 때 포트번호로 구분하여 전송Demutliplexing(역다중화):UDP의 경우: 목적지 포트만 사용같은 포트로 들어오는 요청은 구분 XTCP의 경우: 4-Tuple 사용UDP(User Datagram Protocol)UDP 특징비연결형 → 핸드셰이크 X, 지연 적음비신뢰성 → 유실 & 순서 보장 X이는 애플리케이션 게층에서 챙겨줌혼잡 제어 X간단한 헤더 → 오버헤드 적음체크섬UDP는 데이터가 전송..
[컴퓨터 네트워크 수업] Chapter 2. Application Layer 요약
·
Network
Client-Server vs. P2P클라이언트-서버서버는 항상 켜져있으며 고정 IP를 가짐클라이언트는 서버에 요청하고 서버에 응답하는 구조P2P(Peer-to-Peer)중앙 서버가 없고 피어 간 직접 통신각 피어가 클라이언트이자 서버 역할자체 확장성 뛰어나나 IP 주소 변동으로 인해 관리 복잡프로세스 간 통신 및 소켓프로세스 간 통신같은 호스트 내 → IPC 매커니즘다른 호스트 간 → 메시지 교환소켓: 프로세스와 전송 계층 사이에서 데이터를 보내고 받는 인터페이스애플리케이션 계층 프로토콜 및 전송 서비스 요구사항애플리케이션에 필요한 전송 서비스데이터 무결성타이밍처리량보안애플리케이션 계층 전송 게층 선택 기준데이터 무결성 필요 여부: 신뢰성 필요 → TCP타이밍 민감도: 실시간 요구 → UDP처리량 요구..
[컴퓨터 네트워크 수업] Chapter 1. Introduction
·
Network
1. 인터넷의 기본 개념인터넷이란?정의인터넷은 "네트워크의 네트워크"로, 여러 개의 작은 네트워크(예: 가정, 기업, 모바일 네트워크)가 서로 연결되어 있는 구조구성 요소네트워크 엣지(Edge)호스트(host, end systems): 사용자(클라이언트)와 서버가 여기에 속함액세스 네트워크: 가정용 케이블, DSL, WiFi, 4G/5G 등 다양한 접속 기술을 사용네트워크 코어(Core):라우터(router) 및 스위치(switch): 패킷(데이터 조각)을 서로 전달하며, 여러 네트워크를 연결패킷 스위칭: 데이터가 패킷 단위로 전송되어 각 경로를 통해 전달되는 방식주요 포인트인터넷의 분산성: 수많은 액세스 네트워크와 ISP들이 연결되어 있으며, 중앙집중식 구조가 아님경제적 및 정책적 요인: 네트워크 연결..
[Spring] Spring Transaction 핵심 요약
·
Spring
1. 트랜잭션 적용 확인@Transactional로 선언적 트랜잭션을 사용하면, 실제로 트랜잭션이 적용되는지 확인하기 어렵다.스프링은 AOP 프록시를 이용해 트랜잭션을 적용한다. 따라서 실제 객체가 아닌 프록시 객체가 주입된다.트랜잭션이 활성화되었는지 확인하려면 TransactionSynchronizationManager.isActualTransactionActive() 등을 사용할 수 있다.로그 설정(logging.level.org.springframework.transaction.interceptor=TRACE)을 통해 트랜잭션 시작/종료를 자세히 확인 가능하다.2. 트랜잭션 적용 위치@Transactional을 클래스와 메서드에 동시에 붙이면, 메서드 레벨이 우선순위가 더 높다(더 구체적인 곳이 우..
[Spring] 스프링의 데이터 접근 예외 추상화와 JdbcTemplate
·
Spring
JDBC 체크 예외 문제와 인터페이스서비스 계층은 특정 기술에 종속되지 않고 순수성을 유지하는 것이 좋다. 하지만 JDBC를 사용할 때 SQLException이라는 체크 예외가 발생하여 인터페이스가 특정 기술에 종속되는 문제가 생긴다. 이를 해결하려면 체크 예외를 런타임 예외로 전환하여 처리하는 방법을 사용한다.런타임 예외로 전환하는 이유체크 예외(SQLException)를 사용하면 인터페이스에도 이 예외를 명시해야 해서 특정 기술(JDBC)에 종속된다.런타임 예외를 사용하면 인터페이스에 별도 선언 없이 예외를 던질 수 있어 서비스 계층이 특정 기술에 종속되지 않게 된다.직접 만든 런타임 예외 적용법MyDbException이라는 런타임 예외를 만들어 SQLException을 감싼다.public class..