[DEV] 기록

[SpringBoot] 대용량 엑셀 다운로드를 위한 SXSSFWorkbook

구데타마 2021. 8. 5. 20:21

개요

기존에 Excel 생성 및 다운로드 기능을 구현하는 코드를 공유했었습니다.

https://jaimemin.tistory.com/1768

 

[SpringBoot] Excel 생성 및 다운로드

개요 ElasticSearch로 조회한 목록들을 엑셀로 다운로드할 수 있는 기능을 추가해달라는 요청이 들어와 구현을 해봤습니다. 구현 코드 ExcelController.java ExampleService.java ExcelView.java * 주석으로도 작..

jaimemin.tistory.com

https://jaimemin.tistory.com/2069

 

[SpringBoot] 대용량 엑셀 파일 생성 및 다운로드 삽질기

개요 작년에 이어 올해도 엑셀 파일 생성 및 다운로드 기능을 담당하게 되었습니다. https://jaimemin.tistory.com/1889 [SpringBoot] 대용량 엑셀 다운로드를 위한 SXSSFWorkbook 개요 기존에 Excel 생성 및 다운..

jaimemin.tistory.com

https://jaimemin.tistory.com/2096

 

[SXSSFWorkbook] 엑셀 드롭다운 셀 생성하는 방법

개요 기존에 Excel 생성 및 다운로드 관련 게시글을 여럿 공유했었습니다. https://jaimemin.tistory.com/2069 [SpringBoot] 대용량 엑셀 파일 생성 및 다운로드 삽질기 개요 작년에 이어 올해도 엑셀 파일 생성

jaimemin.tistory.com

https://jaimemin.tistory.com/2191

 

[SpringBoot + Fastexcel] 대용량 엑셀 생성 및 다운로드

개요 여태까지 엑셀 생성 및 다운로드 기능을 구현할 때 Apache Poi 라이브러리를 사용했었고 이와 관련하여 게시글을 여러 번 남겼습니다. https://jaimemin.tistory.com/2069 [SpringBoot] 대용량 엑셀 파일 생

jaimemin.tistory.com

 

해당 기능을 구현하고 한동안 문제가 없었는데 여러 사용자가 동시에 대용량 데이터를 엑셀로 다운로드하면서 Out of Memory Exception이 발생하면서 상용 서버가 다운되는 문제가 발생했습니다.

동시에 여러 쓰레드가 대용량 데이터를 다운로드를 시도하다 보니 서버 CPU 사용량이 98%에 육박했고 이때 GC가 발동하면서 OOM 예외가 발생했던 것입니다.

 

OOM 원인

기존에 작성한 엑셀 다운로드 기능은 크게 두 가지 문제점이 있었습니다.

1. 리스트를 불러올 때 페이징을 적용하지 않고 한번에 불러왔으며

2. 엑셀을 생성할 때 주기적으로 memory flush를 진행하지 못했습니다.

 

위 두 문제점 때문에 앞서 개요에 언급한 것처럼 CPU 사용량이 급격히 올라갔고 이때 GC가 발동하면서 서버가 죽었습니다.

또한, 기존 코드에서도 다행히 SXSSFWorkbook을 사용했는데 SXSSFWorkbook은 다른 workbook과 달리 streaming api를 사용하기 때문에 대용량 데이터 다운로드에 용이합니다. 

 

해결 코드

원인에서도 이미 언급했지만 아래의 두 가지 코드를 적용하면 해결이 됩니다.

1. 리스트를 불러올 때 페이징을 적용하여 여러차례에 걸쳐 불러오고

2. 엑셀을 생성할 때 주기적으로 memory flush를 진행합니다.

 

ExcelController.java


 

ExcelService.java


 

ExcelView.java


 

* 위 코드를 보면 리스트를 한번에 불러오지 않고 만개씩 끊어서 불러오는 것을 볼 수 있고 SXSSFWorkbook도 주기적으로 flush 해주는 것을 확인할 수 있습니다!

 

* 2021-10-14: 코드가 조금 수정되었습니다. 자세한 이유는 아래 포스팅을 참고해주세요.

https://jaimemin.tistory.com/1996

 

[SpringBoot] Execute failed: Invalid row number (1048576) outside allowable range (0..1048575)

개요 기존에 대용량 엑셀 다운로드를 위한 SXSSFWorkbook에 대해 공유한 적이 있습니다. https://jaimemin.tistory.com/1889 [SpringBoot] 대용량 엑셀 다운로드를 위한 SXSSFWorkbook 개요 기존에 Excel 생성 및..

jaimemin.tistory.com

 

요청하는 클라이언트 사이드 (jQuery 예시)


 

* 2021-10-21 추가 코멘트: gateway timeout이 설정되어있을 경우 데이터 양이 많아 time-out이 발생할 수 있습니다.

 

참고자료

https://roytuts.com/handling-large-data-writing-to-excel-using-sxssf-apache-poi/

 

Handling large data writing to Excel using SXSSF Apache POI - Roy Tutorials

Introduction This tutorial will show you an example on handling large data writing to excel using sxssf Apache POI library. Having said that I will show

roytuts.com

https://stackoverflow.com/questions/48040638/how-to-insert-a-linebreak-as-the-data-of-a-cell

 

How to insert a linebreak as the data of a cell?

I use Apache POI 3.16 to create an Excel file. I want to set the data inside a particular cell to have a linebreak : rowConsommationEtRealisation.createCell(0).setCellValue("Consommation (crédits)\r\

stackoverflow.com

 

반응형