배경 및 목표

시트가 유지보수 시 평균 2~3일이 소요되었고, 엑셀 다운로드 로직이 Node 서버에 별도로 존재하여 도메인 로직이 이중으로 관리되고 있었습니다. Node 유지보수가 가능한 인원이 소수였고, 앞으로의 요구 사항과 유지 보수를 위해선 기술 스택 통합이 시급했습니다.

  • Node에 엔티티와 도메인 로직을 복제해서 관리 → 변경 시 양쪽 수정 필요
  • 시트 추가 시 공통 로직을 매번 복사 → 확장성 없음
  • 수만 건 데이터를 메모리에 전부 로드 → OOM 위험

목표

  • 엑셀·도메인 로직 이중 관리를 없애고 Spring 단일 스택으로 통합한다.
  • 수만 건 다운로드에도 메모리가 일정하게 유지되는 안정적 처리를 확보한다.

해결 방법과 해결 후보군

1. 템플릿 메서드 패턴으로 확장성 확보

단순 포팅이 아닌 구조를 재설계했습니다. 모든 시트는 makeSheet → makeHeader → fillData 공통 흐름을 따르고, 새 시트는 AbstractSheet를 상속해서 2개 메서드만 구현하면 됩니다.

2. 멀티 모듈 형태로 기존 도메인 로직 재사용

멀티 모듈을 이용하여 사용중인 도메인 모듈을 재사용하였습니다. 한 곳에서 비즈니스 로직을 관리할 수 있게 되었고, 예상보다 약 4md 정도 빠르게 엑셀 시스템을 이관할 수 있었습니다.

3. SXSSFWorkbook 스트리밍으로 OOM 방지

XSSFWorkbook(전체 메모리 로드) 대신 SXSSFWorkbook(윈도우 방식)을 적용하여, 일정 행만 메모리에 유지하고 나머지는 디스크로 내려서 메모리 사용량을 일정하게 유지했습니다.

sequenceDiagram
    participant E as ExcelDownloader
    participant F as DataFetcher
    participant S as Sheet 구현체
    participant D as Disk
    E->>E: SXSSFWorkbook 생성 (윈도우: N행)
    loop 청크 단위
        E->>F: Slice 쿼리로 N개 조회
        F-->>E: 데이터 청크
        E->>S: 시트에 데이터 전달
        S->>D: 임시 파일 생성
    end
    E->>E: Streaming 응답

결과

지표기존 (Node)개선 (Spring)
도메인 관리이중 관리단일 관리
엑셀 유지보수2~3일0.5일
동시 처리순차 (단일 스레드)병렬 (멀티 스레드)
메모리 안정성OOM 위험스트리밍 처리

모니터링

  • 엑셀 다운로드 시 힙 메모리 사용량(스트리밍으로 일정 유지 여부)을 관측한다.
  • 시트별 생성 시간·실패율을 관측한다.