Fan-Out 구조에서 적체가 확산되는 과정

하나의 느린 서비스가 전체 워크플로우를 멈추게 만든 이유
Fan-Out 구조에서 적체가 확산되는 과정
분산 시스템에서 Fan-Out 구조는 매우 흔하게 사용된다. 하나의 요청이 여러 서비스나 여러 작업으로 동시에 분기되어 병렬 처리되는 구조다. 사용자 주문이 들어오면 결제, 재고 확인, 포인트 적립, 알림 발송, 로그 저장이 동시에 실행되는 형태가 대표적인 예다.
이 구조는 처리 속도를 높이고 확장성을 확보하는 데 매우 효과적이다. 하지만 운영 환경에서는 예상하지 못한 문제가 발생한다. 여러 하위 작업 중 단 하나만 느려져도 전체 워크플로우가 영향을 받기 시작하는 것이다.
특히 Queue 기반 아키텍처나 Workflow Engine 환경에서는 특정 서비스의 적체가 다른 서비스로 빠르게 확산되며 결국 시스템 전체의 Backpressure로 이어질 수 있다.
이번 글에서는 Fan-Out 구조에서 적체가 어떻게 발생하고, 왜 예상보다 훨씬 넓은 범위로 전파되는지 살펴본다.
Fan-Out 구조란 무엇인가
Fan-Out은 하나의 이벤트를 여러 작업으로 분산시키는 구조를 의미한다.
예를 들어 사용자가 상품을 주문하면 다음 작업이 동시에 시작될 수 있다.
- 결제 처리
- 재고 차감
- 배송 준비
- 포인트 적립
- 주문 로그 저장
- 알림 발송
하나의 입력이 여러 하위 프로세스로 나뉘기 때문에 전체 처리 시간은 단축된다.
하지만 문제는 모든 하위 작업이 동일한 속도로 처리되지 않는다는 점이다.
적체는 어디서 시작되는가
대부분의 적체는 특정 하위 서비스의 처리 지연에서 시작된다.
예를 들어 다음과 같은 상황을 생각해보자.
주문 처리 워크플로우
→ 결제 서비스
→ 재고 서비스
→ 알림 서비스
→ 분석 로그 서비스
이 중 알림 서비스가 외부 SMS API 장애로 인해 느려졌다고 가정하자.
처음에는 알림 서비스만 영향을 받는 것처럼 보인다.
하지만 실제로는 그렇지 않다.
적체가 확산되는 과정
1단계: 특정 서비스 Queue 증가
알림 서비스가 요청을 처리하지 못하기 시작한다.
새로운 작업들은 Queue에 계속 쌓인다.
Worker 처리 속도보다 유입 속도가 빨라진다.
2단계: Worker 점유 시간 증가
Worker는 작업 완료를 기다리며 더 오랜 시간 점유된다.
동시에 처리 가능한 작업 수가 감소한다.
결과적으로 Queue 적체 속도는 더욱 빨라진다.
3단계: 상위 Workflow 지연
많은 Workflow Engine은 모든 하위 작업 완료를 기다린 후 다음 단계로 이동한다.
따라서 알림 서비스 하나가 늦어져도 전체 워크플로우가 완료되지 않는다.
결국 주문 처리 자체가 느려지기 시작한다.
4단계: 신규 요청 증가
사용자는 응답이 늦어졌다고 판단한다.
일부 시스템은 자동 재시도를 시작한다.
이 순간 기존 작업 위에 새로운 요청까지 추가된다.
Queue 적체는 더욱 심해진다.
5단계: 전체 시스템 Backpressure
Queue가 가득 차기 시작한다.
Connection Pool이 포화된다.
Thread Pool이 부족해진다.
Worker Latency가 증가한다.
결국 적체가 하나의 서비스에서 끝나지 않고 시스템 전체로 전파된다.
Fan-Out 구조가 특히 위험한 이유
직렬 구조에서는 하나의 서비스만 영향을 받는다.
하지만 Fan-Out 구조에서는 하나의 요청이 여러 하위 작업을 동시에 생성한다.
예를 들어
1개의 요청
↓
10개의 하위 작업 생성
↓
10개 Queue로 분산
이 상황에서 특정 Queue 하나만 느려져도 전체 요청 완료 시간이 증가한다.
트래픽이 증가할수록 문제는 더 심각해진다.
1만 건 요청
↓
10만 개 하위 작업 생성
↓
하위 Queue 일부 포화
↓
전체 워크플로우 지연
즉 Fan-Out 비율이 높을수록 적체 확산 속도도 빨라진다.
실무에서 자주 발생하는 사례
알림 서비스 장애
주문 처리 자체는 정상이다.
하지만 SMS 또는 이메일 발송 서비스가 느려진다.
Workflow가 알림 완료를 기다리도록 설계되어 있으면 주문 처리 전체가 느려진다.
로그 저장 시스템 장애
비즈니스 로직은 정상이다.
그러나 분석 로그 저장 Queue가 포화된다.
로그 적재 완료를 기다리는 구조라면 전체 요청 지연으로 이어질 수 있다.
외부 API 장애
배송 조회 API
결제 검증 API
인증 API
등이 느려질 경우 하위 서비스 적체가 전체 Fan-Out 경로로 확산된다.
흔히 하는 오해
Worker를 늘리면 해결된다
많은 운영자가 가장 먼저 Worker 수를 늘린다.
하지만 실제 병목이 외부 API라면 Worker를 늘려도 효과가 없다.
오히려 더 많은 요청이 병목 지점으로 몰리게 된다.
Queue를 늘리면 해결된다
Queue 확장은 문제를 숨길 뿐이다.
처리 속도가 개선되지 않으면 결국 Queue는 다시 가득 찬다.
더 큰 Queue는 더 긴 지연 시간을 만들 수 있다.
모든 하위 작업을 반드시 기다려야 한다
반드시 그렇지 않다.
알림 발송이나 로그 저장처럼 비핵심 작업은 비동기로 분리하는 것이 훨씬 효율적이다.
적체 확산을 막는 전략
비동기 분리
핵심 비즈니스 로직과 부가 작업을 분리한다.
예를 들어
주문 처리
↓
즉시 완료
↓
알림 발송은 별도 Queue 처리
이 구조가 적체 확산을 크게 줄여준다.
Circuit Breaker 적용
특정 하위 서비스 장애 시 호출을 중단한다.
느린 서비스가 전체 워크플로우를 멈추지 않도록 한다.
Bulkhead 패턴 적용
서비스별 Worker Pool을 분리한다.
알림 서비스 장애가 결제 서비스 Worker를 점유하지 못하도록 격리한다.
Queue 길이 모니터링
다음 지표를 반드시 관찰해야 한다.
- Queue Length
- Queue Wait Time
- Worker Utilization
- Retry Count
- Timeout Rate
- Workflow Completion Time
이 지표들은 적체 확산의 초기 신호를 가장 먼저 보여준다.
자주 묻는 질문
Q. Fan-Out 구조는 문제가 많은 구조인가요?
아니다.
확장성과 처리량 향상을 위해 필수적인 구조다.
문제는 Fan-Out 자체가 아니라 적체를 제어하는 설계가 없는 경우다.
Q. 적체는 왜 예상보다 빠르게 퍼지나요?
하나의 요청이 여러 하위 작업을 생성하기 때문이다.
작은 지연도 Fan-Out을 거치면서 수십 배 규모로 증폭될 수 있다.
Q. 적체가 발생하면 가장 먼저 확인해야 할 것은 무엇인가요?
가장 먼저 Queue Length와 Queue Wait Time을 확인해야 한다.
대부분의 적체는 Queue에서 가장 먼저 관찰된다.
Q. Workflow Engine에서 특히 문제가 되는 이유는 무엇인가요?
많은 Workflow Engine이 모든 하위 작업 완료를 기다리는 Join 구조를 사용하기 때문이다.
하위 작업 하나만 느려져도 전체 워크플로우가 멈출 수 있다.
적체는 생각보다 훨씬 멀리 전파된다
Fan-Out 구조의 가장 큰 장점은 병렬 처리지만, 가장 큰 위험 역시 병렬 처리다. 하나의 느린 서비스가 여러 워크플로우에 영향을 주고, 그 워크플로우가 다시 다른 서비스의 Queue를 점유하면서 적체는 예상보다 훨씬 넓은 범위로 퍼질 수 있다.
실제 장애 분석을 해보면 문제의 시작은 작은 Queue 적체였지만 결과적으로는 Connection Pool 고갈, Worker 지연, Retry Storm, Backpressure 증폭으로 이어지는 경우가 많다.
따라서 Fan-Out 구조를 설계할 때는 처리량보다 먼저 장애 전파 경로를 설계해야 한다. 시스템의 안정성은 빠른 서비스가 아니라, 느려진 서비스를 얼마나 잘 격리할 수 있는지에 의해 결정된다.




댓글 0
첫 댓글을 남겨보세요.