주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 - 5장
이번 주차에는 5장 하나만 나가기로 했다.
비동기 연동
비동기 방식을 사용해도 되는 경우
- 연동에 약간의 시차가 생겨도 문제가 되지 않음
- 실패했을 때 재시도가 가능함
- 실패했을 때 나중에 수동으로 처리 가능
- 실패했을 때 무시해도 괜찮음
비동기 연동을 구현하기 위해 아래에 5가지 방식 소개
별도 스레드로 실행
Thread를 생성하는 방법
java.lang.Thread를 이용해 스레드 객체를 직접 생성한다.
// Runnable 함수형 인터페이스를 구현한 인스턴스를 파라미터로
new Thread(**Runnable** instance).start();
// 함수형 인터페이스 람다식으로 변경 가능
new Thread(() -> code).start();
스레드 풀 사용
ExecutorService 를 이용
각 워커 스레드는 OS 네이티브 스레드 1개와 매핑된다.
new Thread(...) 를 하면 → JVM이 OS에 네이티브 스레드 생성을 요청한다.
고려해아 하는 부분
- 메모리 — 각 스레드마다 스택 메모리
- 컨텍스트 스위칭 비용
- OS 스레드 제한 — 프로세스당 생성 가능한 스레드 수
@Async 어노테이션
스프링 프레임워크에서 비동기 처리를 위해 제공하는 어노테이션
비동기 작업은 다른 스레드에서 실행되므로 호출자에게 예외가 자동 전파되지 않고, 스프링 트랜잭션(@Transactional)도 스레드 로컬 기반이라 호출자의 트랜잭션 범위에 포함되지 않는다. 따라서 비동기 쪽에서 별도의 오류 처리 설계가 필요하다.
Thrashing
스레드를 너무 많이 생성하면 쓰레싱 현상이 생길 수 있다.

OS에서 페이지 교체(page fault) 때문에 CPU가 일을 못 하고 디스크 스왑만 계속되는 상태
메시징 시스템
사용 목적
- 비동기 처리
- 서비스 간 느슨한 결합
- 백프레셔 (Backpressure) 핸들링 — pull 방식으로 소비자가 자신만의 속도로 처리
- 이벤트 기반 아키텍처
- 이벤트 소싱
소비자? 구독자?
- 소비자 : 메시지를 가져와 처리하는 주체. 처리하고 ack하여 큐에서 없애는 느낌
- 구독자 : 특정 이벤트/토픽을 구독해서 알림을 받는 주체.
메시지 종류
- 이벤트 : 이미 발생한 사건/상태 변화 알림 (보통 1:N)
- 커맨드 : 수행해야 할 행위가 담긴 메시지 (보통 1:1)
주요 메시징 시스템 주요 특징
- Kafka
- 수평 확장 용이 → 브로커, 파티션, 소비자를 늘린다.
- 메시지 파일 보관 → 유실되지 않음
- 하나의 토픽에 여러 파티션 가능. 파티션 단위로는 순서 보장하지만, 토픽 수준에서는 순서 보장 X
- 소비자는 메시지 언제든지 재처리 가능 → 소비자는 파티션마다
offset/committed offset을 가지고 있다.offset을 과거로 되돌려서 다시 읽는다는 의미 pull모델
- RabbitMQ
- 메모리에만 메시지 보관하는 큐 설정 사용시 메시지 유실 가능
- 큐에 등록된 순서대로 소비자에 전송 →
push모델 ACK기능 제공- AMQP, STOMP 등 여러 프로토콜 지원
- 게시/구독 패턴, 요청/응답 패턴, Point-to-Point 패턴 지원
- 우선순위 지정해서 처리 순서 변경 가능
- Redis pub/sub
- 메모리 사용 → 지연 시간 짧고, 처리량 높음
- 구독자 없으면 메시지 유실
- 기본적으로 영구 메시지 지원 X
- 모델 단순
글로벌 트랜잭션(분산 트랜잭션)
하나의 논리적 작업을 여러 시스템/DB에 걸쳐 한 번에 성공 또는 한 번에 실패(원자성)처럼 보장하려는 트랜잭션
다음 요소들로 인해 만들기 어렵고 비용도 크다.
- 네트워크 지연/단절
- 부분 실패
- 롤백 불가능한 외부 시스템
2PC (Two-Phase Commit)
구성 요소
- Coordinator : 전체 트랜잭션 관리
- Participants : 트랜잭션에 참여하는 DB나 시스템
Phase 1: Prepare
- 코디네이터가 참여자들에게 커밋할 준비가 되었는지 메시지 전송
- 참여자들은 락을 잡고 커밋 가능한지 Y/N 를 응답
Phase 2: Commit/Rollback
- 모두 YES → 코디네이터가 커밋하라는 메시지 전송
- 하나라도 NO → 코디네이터가 롤백하라는 메시지 전송
한계
- 코디네이터가 죽어버리면..? 참여자가 커밋인지 롤백인지 메시지를 못 받아서 락을 잡고 기다릴 수 있음
- 성능 저하 문제
Saga 패턴
2PC 처럼 강한 원자성을 만들지 않고, 단계별로 커밋하되 실패하면 보상을 줌으로써(보상 트랜잭션) 최종 일관성을 가지게 하는 것.
(최종 일관성 : 두 데이터 저장소 간의 일관성을 보장하지만, 즉시가 아닌 일정 시간 후에 일관성이 맞춰진다. 일시적으로 저장소 간의 불일치 발생 가능)
2가지 구현 방법
- Choreography-Based (이벤트 기반)
- 서비스들이 이벤트를 발행 및 구독하면서 다음 단계를 이어나간다.
- Orchestration-Based
- 지휘자가 있어, 지휘자가 단계나 상태를 관리함
고려해야 하는 부분
- 중복 처리 (멱등성)
- 보상 트랜잭션은 완전한 되돌리기가 아닐 수 있다. (예를 들면, 배송 시작 → 반품 프로세스 진행)
참고자료
SSAFY 특화 프로젝트에서 코어 뱅킹 시스템 만들었을 때 헥사고날 아키텍처를 적용했는데, 그 때 이체 기능(계정 잔고 증감, 원장 기입이 포함된)에 아래 자료를 참고해서 사가 패턴과 보상 트랜잭션을 적용함
토스ㅣSLASH 24 - 보상 트랜잭션으로 분산 환경에서도 안전하게 환전하기
트랜잭션 아웃박스 패턴
- 비즈니스 데이터 변경과 발행할 메시지를 같은 DB 트랜잭션으로
outbox table에 함께 기록해 원자성을 확보하고 - 별도 퍼블리셔가
outbox table을 읽어(폴링/CDC) 메시징 시스템으로 전송함으로써 네트워크/브로커 장애로 인한 메시지 유실과 불일치를 방지하는 패턴
보통 outbox 테이블에 많이 들어가는 것들
- id (PK)
- message_id : 메시지 아이디
- message_type : 메시지 타입
- payload (json/text) : 이벤트 데이터
- status : 발행 상태
- retry_count : 재시도 횟수
- next_retry_at : 다음 재시도 시각
- created_at : 생성 시각
- updated_at : 상태 변경/재시도 시각
- published_at : 발행 시각
- last_error : 마지막 실패 원인
중복 발생/중복 소비 가능성은 충분히 생길 수 있다.
- 메시지 발행 성공했지만, 어떤 문제로 인해 상태 업데이트 실패 가능성
- 그래서 보통
at-least-once+멱등성처리 exactly-once는 네트워크가 껴있는 이상, 이론적으로 매우매우매우 어려움
CDC(Capture Data Change)
DB에서 발생하는 데이터 변경(INSERT/UPDATE/DELETE)을 감지하고 이 이벤트를 다른 시스템에 전달 및 동기화 하는 기법
구현 방식
- Log-based CDC — 트랜잭션 로그를 읽어서 변경 감지
- Trigger-based CDC — 데이터 변경 사항을 DB 내 별도 로그 테이블에 저장해 관리
- Query-based CDC — DB에 쿼리 날려 변동 사항을 조회
- Debezium
- CDC를 위한 오픈소스 플랫폼 (대표적인 log-based cdc)
- Kafka Connect위에서 돌아가는 대표적인 Source Connector
스터디를 하면서…
- 멀티 프로세스? 멀티쓰레드?
- 멀티 프로세스 — 여러 프로세스를 띄움
- 메모리 공간: 서로 분리되어 있음
- 통신: IPC
- 장점
- 격리/안정성. 한 프로세스가 죽어도 다른 프로세스에 영향이 적다
- 보안/권한 분리
- 단점
- 프로세스 생성 및 컨텍스트 스위칭 비용
- 메모리 중복이 생길 수 있음
- 멀티쓰레드 — 한 프로세스 안에 여러 스레드가 실행
- 메모리 공간: 스택 제외 데이터 공유
- 통신: 메모리 공유. 동기화 필요
- 장점
- 생성 및 전환 비용이 프로세스보다 상대적으로 작음
- 메모리 공유로 데이터 전달
- 단점
- 공유 자원으로 인한 race / dead-lock 등 위험 요소
- 한 스레드로 인해 프로세스 전체에 영향을 미칠 수 있다
- 멀티 프로세스 — 여러 프로세스를 띄움
- CompletableFuture — 추가적인 공부 필요
'CS > 스터디' 카테고리의 다른 글
| 이것이 자바다 - 5~6장 (0) | 2026.01.08 |
|---|---|
| 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 - 6, 7장 (0) | 2026.01.05 |
| 이것이 자바다 - 1~4장 (0) | 2025.12.28 |
| 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 - 3, 4장 (0) | 2025.12.24 |
| 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 - 1, 2장 (0) | 2025.12.16 |