Docker环境下使用SXSSFWorkbook创建工作表时程序无响应问题
问题分析与解决方案
核心现象
在Docker容器内执行Apache POI生成Excel的代码时,日志输出到WORKBOOK CREATED后无后续内容,程序挂起;但在容器外运行完全正常。环境为Apache POI 4.1.2 + JDK 11.0.16,已尝试指定具备全读写权限的临时目录,但问题仍未解决。
可能原因与对应解决方案
1. Docker容器内存资源不足
SXSSFWorkbook在写入文件时依赖临时文件缓存,若容器内存配额过低,会导致JVM内存紧张或IO操作阻塞。
- 排查:执行
docker stats查看目标容器的内存使用率,确认是否存在内存耗尽情况。 - 解决:启动容器时增加内存限制,例如:
或在docker-compose.yml中配置:docker run -m 2g <镜像名>services: your-service: mem_limit: 2g
2. 容器内文件描述符数量不足
SXSSF处理文件时会创建多个临时文件,若容器默认的文件描述符上限(通常为1024)过低,会导致IO操作卡住。
- 排查:进入容器执行
ulimit -n,查看当前文件描述符限制。 - 解决:启动容器时调整上限:
或在docker-compose.yml中配置:docker run --ulimit nofile=65535:65535 <镜像名>services: your-service: ulimits: nofile: soft: 65535 hard: 65535
3. 临时目录权限实际不匹配
虽然预先创建了目录并设置全权限,但容器内运行应用的用户(如tomcat)可能与目录所有者不一致,导致实际无读写权限。
- 排查:进入容器执行
ls -ld /usr/local/tomcat/temp/reporting-service-16769203353988068118/,确认目录所有者与应用运行用户是否一致。 - 解决:在Dockerfile或启动脚本中添加权限修改命令:
(替换chown -R tomcat:tomcat /usr/local/tomcat/temp/reporting-service-16769203353988068118/tomcat:tomcat为实际应用运行的用户和组)
4. Apache POI 4.1.2兼容性问题
POI 4.1.2与JDK 11在Docker环境下可能存在IO阻塞的特定bug。
- 解决:
- 升级POI版本至4.1.3及以上稳定版(如5.2.5),新版本修复了大量JDK11相关兼容性问题。
- 改用
try-with-resources自动管理资源,避免手动关闭流导致的泄漏:try (Workbook workbook = new SXSSFWorkbook(new XSSFWorkbook(), SXSSFWorkbook.DEFAULT_WINDOW_SIZE); FileOutputStream fos = new FileOutputStream(file)) { workbook.createSheet(WorkbookUtil.createSafeSheetName("TEST")); log.info("SHEET CREATED"); workbook.write(fos); workbook.dispose(); } catch (Exception ex) { log.error("EXPORT FAILED", ex); }
额外排查手段
- 开启JVM GC日志:在容器启动的JVM参数中添加
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps,排查是否存在GC停顿或内存溢出。 - 查看容器系统日志:执行
docker logs <容器ID>或宿主机dmesg命令,确认是否有IO相关错误。
内容的提问来源于stack exchange,提问作者Deewendra Shrestha
相关产品推荐
相关产品推荐

