fix: 修复下载jtl过大导致oom的问题

This commit is contained in:
Captain.B 2021-02-02 10:53:55 +08:00
parent eb97cbeb25
commit 99b46de258
4 changed files with 45 additions and 13 deletions

View File

@ -0,0 +1,15 @@
package io.metersphere.base.mapper.ext;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.io.InputStream;
public interface ExtFileContentMapper {
@Select(value = {
"SELECT file ",
"FROM file_content ",
"WHERE file_id = #{id, jdbcType=VARCHAR}"
})
InputStream selectZipBytes(@Param("id") String id);
}

View File

@ -16,9 +16,6 @@ import io.metersphere.performance.controller.request.ReportRequest;
import io.metersphere.performance.service.ReportService;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@ -137,11 +134,7 @@ public class PerformanceReportController {
}
@GetMapping("/jtl/download/{reportId}")
public ResponseEntity<byte[]> downloadJtl(@PathVariable String reportId) {
byte[] bytes = reportService.downloadJtl(reportId);
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType("application/octet-stream"))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + reportId + ".jtl\"")
.body(bytes);
public void downloadJtlZip(@PathVariable String reportId, HttpServletResponse response) {
reportService.downloadJtlZip(reportId, response);
}
}

View File

@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.ExtFileContentMapper;
import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
import io.metersphere.commons.constants.PerformanceTestStatus;
import io.metersphere.commons.constants.ReportKeys;
@ -23,11 +24,15 @@ import io.metersphere.performance.engine.EngineFactory;
import io.metersphere.service.FileService;
import io.metersphere.service.TestResourceService;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
@ -52,6 +57,8 @@ public class ReportService {
private LoadTestReportDetailMapper loadTestReportDetailMapper;
@Resource
private FileService fileService;
@Resource
private SqlSessionFactory sqlSessionFactory;
public List<ReportDTO> getRecentReportList(ReportRequest request) {
List<OrderRequest> orders = new ArrayList<>();
@ -284,11 +291,28 @@ public class ReportService {
return JSON.parseArray(content, ChartsData.class);
}
public byte[] downloadJtl(String reportId) {
/**
* 流下载 jtl zip
*/
public void downloadJtlZip(String reportId, HttpServletResponse response) {
LoadTestReportWithBLOBs report = getReport(reportId);
if (StringUtils.isBlank(report.getFileId())) {
throw new RuntimeException(Translator.get("load_test_report_file_not_exist"));
}
return fileService.loadFileAsBytes(report.getFileId());
response.setHeader("Content-Disposition", "attachment;fileName=" + reportId + ".zip");
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
ExtFileContentMapper mapper = sqlSession.getMapper(ExtFileContentMapper.class);
try (InputStream inputStream = mapper.selectZipBytes(report.getFileId())) {
ServletOutputStream outputStream = response.getOutputStream();
byte[] buffer = new byte[1024 * 4];
int read;
while ((read = inputStream.read(buffer)) > -1) {
outputStream.write(buffer, 0, read);
}
} catch (Exception e) {
LogUtil.error(e);
MSException.throwException(e);
}
}
}
}

View File

@ -293,12 +293,12 @@ export default {
};
this.result = this.$request(config).then(response => {
const content = response.data;
const blob = new Blob([content]);
const blob = new Blob([content], {type: "application/octet-stream"});
if ("download" in document.createElement("a")) {
// IE
// chrome/firefox
let aTag = document.createElement('a');
aTag.download = this.reportId + ".jtl";
aTag.download = this.reportId + ".zip";
aTag.href = URL.createObjectURL(blob);
aTag.click();
URL.revokeObjectURL(aTag.href)