处理多个请求时的Apache Poi性能问题

时间:2018-07-27 11:01:23

标签: java server apache-poi streaming

我正在尝试使用Apache Poi将数据库表中的数据写入Xlsx文件。首先,我使用XSSFWorkbook进行了尝试。我想写几乎100万个具有100个属性的元组。所以我在使用XSSFWorkbook时遇到OutOfMemory错误,因为它在写入之前将整个数据加载到内存中。

所以我尝试使用SXSSFWorkbook。它支持流传输,因此内存使用率没有问题。当有单个客户端请求时,它非常有用。确切地说,响应花费了将近1分30秒(对于单个客户端)。我在机器上使用的是Apache Tomcat 8.5.32服务器。

我从apache文档中了解到SXSSFWorkbook仅在内存中保留指定数量的行,并将其他行写入临时文件。

我的代码分为两部分。

    SXSSFWorkbook wb = new SXSSFWorkbook(100);
    Sheet sh = wb.createSheet();

    String name = UUID.randomUUID().toString().replace("-", "") + ".xlsx";

    try {

        String sql = "select * from users";
        ResultSet rs = stmt.executeQuery(sql);
        System.out.println("Query finished");

        int i=1;
        while(rs.next()) {
            User user = getUserByRS(rs);

            Row row = sh.createRow(i++);
            Cell cell1 = row.createCell(0);
            cell1.setCellValue(user.getUid());
            for(int j=1;j<100;j+=2) {
                Cell cell2 = row.createCell(j);
                cell2.setCellValue(user.getUsername());

                Cell cell3 = row.createCell(j+1);
                cell3.setCellValue(user.getText());
            }
            if(i%40000==0) {
                Date mydate = new Date();

                System.out.println( (i/4000) + "% completed"  + " System date : "+ mydate.toString());

                out.println( (i/4000) + "% completed"  + " System date : "+ mydate.toString());
                out.println(Runtime.getRuntime().totalMemory() + " " + Runtime.getRuntime().freeMemory());
                System.gc();
            }

        }

这是我代码的第一部分。此代码从数据库获取数据(SQL查询中已处理了来自数据库的数据流。因此这里没有内存问题)并将其写入SXXFSWorkbook,后者将数据写入中间的临时磁盘文件。如果有一个客户端请求,这部分代码将花费近40秒,而如果有6-8个客户端请求(一起)则将花费5-6分钟。为什么?。

来到我的代码的第二部分。

        FileOutputStream out1 = new FileOutputStream(new File("/Users/test/Desktop/reports/" + name));
        wb.write(out1);
        out1.close();  

这是代码的一部分,其中中间磁盘文件中的数据被写入到我的响应文件的输出流中。如果是单个文件,则将花费近40秒,如果是6-8个客户端请求,则将花费大约10-11分钟。为什么?

此外,速度随内存中加载的行数而变化。例如,在100行的情况下,为6-8个客户请求提供服务大约需要20分钟,而在10行的情况下,相同的则大约需要12-15分钟。为什么?

此外,所有请求的响应文件将同时写入。由于服务器将每个请求作为单独的线程处理,为什么会发生这种情况?

0 个答案:

没有答案