배경 및 목표

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

graph LR
    subgraph AS_IS["❌ 기존: 기술 스택 분산"]
        A["Spring 서버"] -->|"도메인 로직"| D1["DB"]
        B["Node 서버"] -->|"엑셀 로직 + 도메인 복제"| D1
    end
    subgraph TO_BE["✅ 개선: 단일 스택"]
        C["Spring 서버"] -->|"도메인 + 엑셀"| D2["DB"]
    end
    AS_IS -.->|"포팅"| TO_BE
  • Node에 엔티티와 도메인 로직을 복제해서 관리 → 변경 시 양쪽 수정 필요
  • 시트 추가 시 공통 로직을 매번 복사 → 확장성 없음
  • 수만 건 데이터를 메모리에 전부 로드 → OOM 위험

목표

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

해결 방법과 해결 후보군

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

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

classDiagram
    class AbstractSheet {
        <<abstract>>
        +makeSheet(data, workbook)
        #makeHeader(sheet)*
        #fillData(data, sheet)*
    }
    class 지원자정보Sheet {
        #makeHeader(sheet)
        #fillData(data, sheet)
    }
    class 평가정보Sheet {
        #makeHeader(sheet)
        #fillData(data, sheet)
    }
    AbstractSheet <|-- 지원자정보Sheet
    AbstractSheet <|-- 평가정보Sheet

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

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

graph TB
    subgraph problem["도메인 로직 재사용"]
        A["api 모듈"] --> D
        B["worker 모듈"] --> D
        C["파일 처리 모듈(신규)"] --> D
        D["도메인 모듈"]
    end

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 위험스트리밍 처리

모니터링

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