본문 바로가기
컴퓨터 활용(한글, 오피스 등)/기타

레거시 시스템에서 클라우드 전환 후 엑셀 다운로드가 안 될 때 해결법

by 3604 2025. 5. 26.
728x90

출처: https://velog.io/@pkt/TS-%EB%8C%80%EC%9A%A9%EB%9F%89-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%9D%98-%EC%97%91%EC%85%80-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C-%EC%98%A4%EB%A5%98

[TS] 레거시 시스템에서 클라우드 전환 후 엑셀 다운로드가 안 될 때 해결법

 
 
1. 배경

레거시 시스템에서 서버를 클라우드로 이관하고 나서부터 평균 20,000건 이상의 데이터를 엑셀로 다운로드 받아야 하는데, 약 6,000건 정도부터 다운로드가 되지 않는 이슈가 발생했습니다.

OS : Window 2012 R2
Server : Apache Tomcat 8
Infra : Azure
Back-end : Java, Spring
Front-end : JSP, Javascript (grid : jqgrid)



2. 분석

우선 엑셀 다운로드 방식을 분석해 보니, 다음과 같았습니다.

  1. 클라이언트가 요청하면 grid의 전체 데이터셋을 JSON으로 서버로 전송하고,
  2. 서버에서는 POI의 SXSSFWorkbook을 사용하여 스트리밍 방식으로 Excel 생성
🔍 POI란?
Apache POI(Poor Obfuscation Implementation)는 Java에서 Microsoft Office 파일(Excel, Word, PowerPoint 등)을 읽고 쓸 수 있게 해주는 라이브러리입니다.
  
🔍SXSSFWorkbook의 주요 특징
- 스트리밍 방식으로 대용량 Excel 파일 생성 가능
- 메모리에 일정 개수의 행만 유지(기본값 100개)하고 초과분은 임시파일로 디스크에 저장
- 한 시트당 최대 약 백만 행(2^20 - 1)까지 처리 가능
- 대용량 데이터 처리에 최적화되어 있지만, 이전 행을 다시 읽거나 수정하는 것은 불가능
- XSSFWorkbook보다 메모리 사용량이 훨씬 적음

✔️Check List
아래 3가지 정도로 추려서 살펴보았습니다.

1. Server 설정이 충분한가?

  • 메모리 제한
    → JVM 메모리가 초기 128MB, 최대 256MB로 설정되어 있으므로 부족🔴
  • 연결 유지 시간 및 동시 처리량
    → connectionTimeout이 60초밖에 안 되고, acceptCount, keepAliveTimeout등 필요한 설정이 없음🔴

2. 현재 로직이 대용량 처리 방식에 적합한 방식인가?

  • 스트리밍 방식으로 대용량 처리 방식에 효율적인 방식🟢
  • 모든 데이터를 JSON형태로 한 번에 메모리에 로드하는 방식은 비효율적인 방식🔴

3. 클라우드(Azure) 서버 설정 중 파일 제한은 없는가?

  • 클라우드 담당자에게 제한되는 사항은 없다고 컨펌받음🟢


3. 해결방안


1. Server 설정 변경

  • 메모리 최적화
변경 항목기존 설정 (AS-IS)변경 설정 (TO-BE)효과
-Xms (초기 Heap 크기) 128MB 512MB 애플리케이션 실행 시 안정성 향상
-Xmx (최대 Heap 크기) 256MB 1024MB 대량 데이터 처리 시 메모리 부족 문제 해결
-XX:+UseG1GC 없음 추가 효율적인 가비지 컬렉션으로 응답 속도 개선
-XX:MaxGCPauseMillis=200 없음 추가 GC로 인한 지연 최소화
-XX:+HeapDumpOnOutOfMemoryError 없음 추가 메모리 문제 발생 시 원인 분석 가능

  • 안정성 강화
변경 항목기존 설정 (AS-IS)변경 설정 (TO-BE)효과
connectionTimeout 60초 (60000ms) 600초 (600000ms) 대용량 요청 시 충분한 처리 시간 확보
maxThreads 300 500 동시 접속 처리량 증가
acceptCount 없음 200 대기 중인 요청을 더 많이 수용
keepAliveTimeout 없음 120초 (120000ms) 연결을 유지하여 성능 향상
maxHttpHeaderSize 기본값 (8KB) 64KB 큰 요청 헤더 처리 가능
socketBuffer 기본값 64KB 네트워크 성능 최적화
🔍 타임아웃의 중요성
1) 서버 리소스 관리
2) 불필요한 연결 방지
3) 대용량 데이터 전송 시 연결 유지

만약, 60,000ms로 설정된 상태에서 다운로드를 시도하면 다음과 같은 문제가 발생할 수 있습니다.
1) 데이터 처리 중 타임아웃 발생
2) 다운로드가 중간에 끊김
3) 불완전한 엑셀 파일이 생성

2. 데이터 처리 방식 변경

전체 데이터를 한 번에 로드하는 JSON 방식에서 작은 단위로 분할해서 로드하는 Chunk 방식으로 변경하였습니다.

🔍 데이터셋 비교

비교 항목JSON 방식Chunk 방식
메모리 사용 전체 데이터를 한 번에 메모리에 로드하여 높은 메모리 사용 청크 단위로 분할하여 낮은 메모리 사용
브라우저 성능 대용량 데이터 시 브라우저 멈춤/느려짐 현상 발생 청크 단위 처리로 브라우저 반응성 유지
처리 속도 작은 데이터셋의 경우 빠른 처리 청크 단위 통신으로 인한 약간의 오버헤드 발생
네트워크 부하 한 번에 대량의 데이터 전송으로 타임아웃 위험 분산된 네트워크 부하로 안정적 전송
에러 복구 전송 실패 시 전체 재시도 필요 실패한 청크만 재전송 가능
진행률 표시 전체 용량 기준 진행률만 표시 가능 청크 단위로 세밀한 진행률 표시 가능
구현 복잡도 단순한 구현 상대적으로 복잡한 구현 필요
서버 부하 순간적인 높은 서버 부하 발생 분산된 서버 부하로 안정적 처리
[요약]
Chunk 방식은 대용량 데이터 처리에 있어 메모리 사용량과 시스템 안정성 측면에서 큰 이점을 제공하지만, 
작은 데이터셋의 경우 JSON 방식을 사용하는 것이 효율적입니다.

4. 결론

Server 설정을 최적화한 것만으로도 문제가 해결되었습니다.
특히, 메모리가 부족한 것이 주 원인이므로 메모리 최적화가 주효했습니다.

728x90