728x90
[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. 분석
우선 엑셀 다운로드 방식을 분석해 보니, 다음과 같았습니다.
- 클라이언트가 요청하면 grid의 전체 데이터셋을 JSON으로 서버로 전송하고,
- 서버에서는 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 설정 변경
- 메모리 최적화
| -Xms (초기 Heap 크기) | 128MB | 512MB | 애플리케이션 실행 시 안정성 향상 |
| -Xmx (최대 Heap 크기) | 256MB | 1024MB | 대량 데이터 처리 시 메모리 부족 문제 해결 |
| -XX:+UseG1GC | 없음 | 추가 | 효율적인 가비지 컬렉션으로 응답 속도 개선 |
| -XX:MaxGCPauseMillis=200 | 없음 | 추가 | GC로 인한 지연 최소화 |
| -XX:+HeapDumpOnOutOfMemoryError | 없음 | 추가 | 메모리 문제 발생 시 원인 분석 가능 |
- 안정성 강화
| 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
'컴퓨터 활용(한글, 오피스 등) > 기타' 카테고리의 다른 글
| 오픈SW 모든 문서를 마크다운으로! 마이크로소프트가 선보인 혁신적 문서 변환 도구 'MarkItDown' (0) | 2025.05.29 |
|---|---|
| 프로세스에서 입력/출력 의미 (0) | 2025.05.26 |
| 교육센터 (0) | 2025.05.23 |
| Windsurf 사용 가이드 (0) | 2025.05.21 |
| 크롬 새 탭 페이지 바탕 바로가기 아이콘 변경방법 (0) | 2025.05.19 |