본문 바로가기
1. 개발/1.8. ActiveMQ

Large Message 전송 중 네트워크 단절 시 부분 데이터 처리 방식은?

by 엉짱 2026. 3. 25.
반응형

Large Message 전송 중 네트워크 단절 시 부분 데이터 처리 방식은?

엔터프라이즈 환경에서 수백 메가바이트(MB)에서 수 기가바이트(GB)에 달하는 대용량 파일이나 로그 덤프를 메시지 브로커를 통해 전송할 때, 가장 두려운 적은 바로 '네트워크의 불확실성'입니다.

일반적인 단문 메시지는 찰나의 순간에 전송되므로 성공 아니면 실패라는 이분법적 결과만 존재합니다. 하지만 1GB 크기의 'Large Message'를 스트리밍 방식으로 전송하는 도중, 500MB 지점에서 네트워크 케이블이 뽑히거나 스위치 장비에 장애가 발생한다면 어떻게 될까요? 브로커 디스크에 남겨진 500MB의 찌끄러기(부분 데이터)는 어떤 운명을 맞이하게 되며, 시스템은 이 불안전한 상태를 어떻게 복구할까요?

이 가이드에서는 ActiveMQ Artemis가 대용량 메시지 전송 중 발생하는 네트워크 단절 및 예기치 않은 세션 종료 상황에서, 부분 데이터를 어떻게 격리하고 시스템의 무결성을 방어하는지 그 내부 메커니즘을 상세히 해부합니다.


1. Large Message 전송의 트랜잭션적 특징

부분 데이터의 처리 방식을 이해하려면, 대용량 메시지가 브로커에 인입되는 전체 파이프라인을 먼저 이해해야 합니다.

프로듀서(Producer)가 대용량 메시지 전송을 시작하면, 클라이언트 API는 거대한 스트림을 작은 청크(Chunk) 단위로 쪼개어 브로커로 보냅니다. 브로커는 이를 메모리에 올리지 않고 즉시 large-messages 디렉토리에 고유한 파일명(예: 12345.msg)으로 순차 기록합니다.

여기서 가장 중요한 핵심은, 파일 전송이 100% 완료되고 프로듀서가 '전송 완료(End of Stream)' 신호를 보내기 전까지는, 이 메시지가 목적지 큐(Queue)에 논리적으로 라우팅되지 않는다는 점입니다. 즉, 물리적인 디스크에는 파일이 써지고 있지만, 컨슈머(Consumer)의 눈에는 이 메시지가 아예 존재하지 않는 투명한 상태로 유지됩니다.


2. 생산자(Producer) 측 네트워크 단절: 고아 파일(Orphan File)의 발생과 소멸

프로듀서가 1GB 중 500MB를 전송하다가 네트워크가 끊어지면 다음과 같은 방어 메커니즘이 연쇄적으로 작동합니다.

A. 라우팅 차단 (Dirty Read 방지)
앞서 언급했듯, 전송 완료 시그널을 받지 못했으므로 브로커는 이 500MB짜리 불완전한 메시지를 큐의 대기열에 올리지 않습니다. 따라서 컨슈머가 반쪽짜리 깨진 파일을 다운로드하여 비즈니스 로직에 심각한 오류(Dirty Read)를 일으키는 상황은 원천적으로 차단됩니다.

B. 세션 타임아웃과 자원 회수 (Cleanup)
브로커의 디스크에는 500MB 용량의 쓸모없는 '.msg' 파일이 남게 됩니다. 이를 고아 파일(Orphan File)이라고 부릅니다.
브로커는 클라이언트와의 TCP 커넥션이 끊어졌음을 감지하거나(Keep-alive 실패), 해당 세션이 타임아웃되었다고 판단하는 즉시, 해당 세션에 묶여있던 모든 임시 자원을 회수하는 롤백(Rollback) 절차에 돌입합니다. 이때 large-messages 폴더에 생성 중이던 불완전한 파일 역시 운영체제 파일 시스템 레벨에서 즉각적으로 완전 삭제(Delete) 처리됩니다. 이를 통해 디스크 공간 누수(Leak)를 방지합니다.


3. 소비자(Consumer) 측 네트워크 단절: 재전송(Redelivery)과 멱등성

반대로 프로듀서는 1GB 전송을 무사히 마쳤는데, 컨슈머가 큐에서 이 대용량 메시지를 스트리밍으로 다운로드 받다가 500MB 지점에서 네트워크가 단절된다면 어떻게 될까요?

A. 메시지 상태 롤백 (Unacknowledged)
컨슈머가 전체 파일을 다 내려받고 처리를 완료했다는 수신 확인(ACK)을 브로커에 보내지 못하고 연결이 끊어졌으므로, 브로커는 해당 메시지를 처리 실패로 간주합니다. 디스크에 있는 1GB짜리 원본 '.msg' 파일은 삭제되지 않고 안전하게 보존되며, 논리적인 큐에서도 다시 '수신 대기(Ready)' 상태로 롤백됩니다.

B. 재배달(Redelivery) 메커니즘
네트워크가 복구되고 컨슈머가 다시 큐에 접속하면, 브로커는 해당 1GB 메시지를 처음부터 다시 전송(Redelivery)합니다. 브로커 레벨에서는 파일 다운로드 매니저(FTP 등)처럼 '500MB 지점부터 이어받기(Resume)' 기능을 기본적으로 지원하지 않습니다.
따라서 컨슈머 측 비즈니스 애플리케이션은 동일한 메시지를 다시 처음부터 받더라도 시스템의 상태가 꼬이지 않도록 완벽한 멱등성(Idempotency)을 갖추고 있어야 하며, 임시로 다운받던 500MB 찌끄러기 파일을 로컬에서 스스로 삭제하는 방어 로직을 구현해야 합니다.


4. 이어받기(Resume) 부재의 극복: 아키텍처 모범 사례

Artemis를 비롯한 대부분의 메시지 브로커는 비동기 이벤트 전달에 최적화되어 있지, 전문적인 대용량 파일 전송 프로토콜(FTP, rsync)이 아닙니다. 따라서 네트워크 단절 시 처음부터 다시 전송해야 하는 오버헤드를 극복하기 위해 엔터프라이즈 환경에서는 다음과 같은 우회 아키텍처를 적용합니다.

A. 애플리케이션 레벨의 청크 분할 (Application Chunking)
1GB짜리 단일 Large Message를 브로커에 던지는 대신, 프로듀서 애플리케이션 로직에서 원본 파일을 10MB짜리 100개의 독립적인 메시지로 쪼개어 순서 정보(Sequence ID)와 함께 전송하는 방식입니다. 이 경우 50번째 메시지에서 끊어지면, 나중에 50번째 메시지부터 다시 전송/수신하면 되므로 네트워크 대역폭 낭비를 막을 수 있습니다.

B. 클레임 체크 패턴 (Claim Check Pattern) - 가장 권장되는 표준
메시지 브로커를 파일 전송 용도로 사용하는 것 자체를 안티 패턴(Anti-Pattern)으로 봅니다.
초대용량 파일은 브로커가 아닌 전용 오브젝트 스토리지(AWS S3, MinIO 등)에 먼저 업로드합니다. 업로드가 완료되면, 프로듀서는 해당 파일을 다운로드할 수 있는 'URL 링크(접근 주소)'만을 담은 수십 바이트짜리 아주 가벼운 단문 메시지를 브로커 큐에 발행합니다.
컨슈머는 큐에서 URL을 꺼낸 뒤, 실제 파일 다운로드는 이어받기가 완벽히 지원되는 HTTP/S3 클라이언트를 통해 스토리지에서 직접 수행합니다. 브로커의 I/O 부하를 완전히 제거하고 시스템의 안정성을 극대화하는 최고의 아키텍처입니다.


결론적으로 Artemis의 Large Message 기능은 네트워크 단절 시 불완전한 부분 데이터를 철저히 폐기하고 롤백함으로써 시스템의 정합성을 완벽하게 지켜냅니다. 하지만 '이어받기'가 불가능하다는 태생적 한계가 존재하므로, 네트워크가 극도로 불안정하거나 파일 크기가 무지막지하게 크다면 클레임 체크 패턴과 같은 아키텍처 레벨의 해결책을 병행하여 도입하시기 바랍니다.

반응형