接口线上调用时间长排查

线上发现这个接口调用时间非常长 花费2min

public void exportExcel(GetHistoryDataDTO getHistoryDataDTO, HttpServletResponse httpResponse) {
        List<Map<String, String>> dataList = new ArrayList<>();
        getHistoryDataDTO.getGetHistoryDataChildren().get(0).setConfCode("COAGULANT_FLOW");
        long l1 = System.currentTimeMillis();
        List<GetHistoryDataVO> addAlumCompareData = this.getAddAlumCompareData(getHistoryDataDTO);
        long l2 = System.currentTimeMillis();
        log.info("==========exportExcel=========  t1:{}", (l2 - l1) / 1000.0);
        getHistoryDataDTO.getGetHistoryDataChildren().get(0).setConfCode("TURBIDITY_OUT");
        List<GetHistoryDataVO> historyData = this.getHistoryData(getHistoryDataDTO);
        long l3 = System.currentTimeMillis();
        log.info("==========exportExcel=========  t2:{}", (l3 - l2) / 1000.0);
        Date currentTime = getHistoryDataDTO.getBeginTime();
        while (currentTime.getTime() < getHistoryDataDTO.getEndTime().getTime()) {
            String time = DateUtil.formatDateTime(currentTime);
            Map<String, String> data = new HashMap<>();
            data.put("time", time);
            if (CollectionUtils.isNotEmpty(addAlumCompareData)) {
                List<GetHistoryDataChildVO> data1 = addAlumCompareData.get(0).getData();
                if (Objects.nonNull(data1)) {
                    Map<String, GetHistoryDataChildVO> collect = data1.stream().collect(Collectors.toMap(v -> DateUtil.formatDateTime(v.getDataTime()), Function.identity()));
                    GetHistoryDataChildVO vo = collect.get(time);
                    if (Objects.nonNull(vo)) {
                        BigDecimal addAlumFlowOneValue = vo.getOneActualValue();
                        data.put("addAlumFlowOneValue", addAlumFlowOneValue == null ? "" : addAlumFlowOneValue.toString());
                        BigDecimal addAlumFlowTwoValue = vo.getActualValue();
                        data.put("addAlumFlowTwoValue", vo.getActualValue() == null ? "" : addAlumFlowTwoValue.toString());
                        BigDecimal addAlumFlowPre = vo.getCalculatedValue();
                        data.put("addAlumFlowPre", vo.getCalculatedValue() == null ? "" : addAlumFlowPre.toString());
                    }
                }
            }
            if (CollectionUtils.isNotEmpty(historyData)) {
                List<GetHistoryDataChildVO> data1 = historyData.get(0).getData();
                if (CollectionUtils.isNotEmpty(data1)) {
                    Map<String, GetHistoryDataChildVO> collect = data1.stream().collect(Collectors.toMap(v -> DateUtil.formatDateTime(v.getDataTime()), Function.identity()));
                    GetHistoryDataChildVO vo = collect.get(time);
                    if (Objects.nonNull(vo)) {
                        BigDecimal turbidityValue = vo.getActualValue();
                        data.put("turbidityValue", vo.getActualValue() == null ? "" : turbidityValue.toString());
                        BigDecimal turbidityValuePre = vo.getCalculatedValue();
                        data.put("turbidityValuePre", vo.getCalculatedValue() == null ? "" : turbidityValuePre.toString());
                    }
                }
            }
            dataList.add(data);
            currentTime = DateUtil.offsetMinute(currentTime, 2);
        }
        long l4 = System.currentTimeMillis();
        log.info("==========exportExcel=========  t3:{}", (l4 - l3) / 1000.0);
        log.info("exportExcelMonth dto:{}", JSON.toJSONString(dataList));
        ExcelWriter excelWriter = null;
        Map<String, Object> extMap = new HashMap<>();
        extMap.put("startTime", DateUtil.formatDateTime(getHistoryDataDTO.getBeginTime()));
        extMap.put("endTime", DateUtil.formatDateTime(getHistoryDataDTO.getEndTime()));
        ExcelUtil.configResponse(httpResponse);
        // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
        // {} 代表普通变量 {.} 代表是list的变量 {前缀.} 前缀可以区分不同的list
        InputStream inputStream = null;
        File reportFile = null;
        try {
            inputStream = new ClassPathResource("template/addAlum.xlsx").getInputStream();
            reportFile = new File("addAlum.xlsx");
            FileUtils.copyInputStreamToFile(inputStream, reportFile);
            excelWriter = EasyExcel.write(httpResponse.getOutputStream()).excelType(ExcelTypeEnum.XLSX).withTemplate(reportFile.getPath()).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            // 简单的说 如果你的模板有list,且list不是最后一行,下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).direction(WriteDirectionEnum.VERTICAL).build();
            //填充列表数据
            excelWriter.fill(extMap, fillConfig, writeSheet);
            //log.info("exportExcelMonth dataList:{}", JSON.toJSONString(dataList));
            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(dataList)) {
                excelWriter.fill(dataList, fillConfig, writeSheet);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("导出异常:{}", e.getMessage());
        } finally {
            if (Objects.nonNull(reportFile) && reportFile.exists()) {
                boolean delete = reportFile.delete();
                log.info("文件删除" + (delete ? "成功" : "失败"));
            }
            // 千万别忘记close 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    log.error("文件流异常", e);
                }
            }
        }
        long l5 = System.currentTimeMillis();
        log.info("==========exportExcel=========  t4:{}", (l5 - l4) / 1000.0);
    }在这里插入代码片

打日志排查后发现问题出在t3,是循环里的代码花费的时间太长。
在服务上查看jvm状态发现在调用时不停的进行young gc导致时间花费太长

排查这段代码的大对象是在循环里面大对象不停的被创建

Map<String, GetHistoryDataChildVO> collect = data1.stream().collect(Collectors.toMap(v -> DateUtil.formatDateTime(v.getDataTime()), Function.identity()));

优化之后时间明显缩短,将大对象单独只操作一次即可

if (CollectionUtils.isNotEmpty(addAlumCompareData)) {
            List<GetHistoryDataChildVO> data1 = addAlumCompareData.get(0).getData();
            if (Objects.nonNull(data1)) {
                data1.forEach(v -> addAlumMap.put(DateUtil.formatDateTime(v.getDataTime()), v));
            }
        }
        if (CollectionUtils.isNotEmpty(historyData)) {
            List<GetHistoryDataChildVO> data1 = historyData.get(0).getData();
            if (Objects.nonNull(data1)) {
                data1.forEach(v -> turbidityMap.put(DateUtil.formatDateTime(v.getDataTime()), v));
            }
        }
        while (currentTime.getTime() < getHistoryDataDTO.getEndTime().getTime()) {
            String time = DateUtil.formatDateTime(currentTime);
            Map<String, String> data = new HashMap<>();
            data.put("time", time);
            GetHistoryDataChildVO vo = addAlumMap.get(time);
            if (Objects.nonNull(vo)) {
                BigDecimal addAlumFlowOneValue = vo.getOneActualValue();
                data.put("addAlumFlowOneValue", addAlumFlowOneValue == null ? "" : addAlumFlowOneValue.toString());
                BigDecimal addAlumFlowTwoValue = vo.getActualValue();
                data.put("addAlumFlowTwoValue", vo.getActualValue() == null ? "" : addAlumFlowTwoValue.toString());
                BigDecimal addAlumFlowPre = vo.getCalculatedValue();
                data.put("addAlumFlowPre", vo.getCalculatedValue() == null ? "" : addAlumFlowPre.toString());
            }
            GetHistoryDataChildVO turbidity = turbidityMap.get(time);
            if (Objects.nonNull(turbidity)) {
                BigDecimal turbidityValue = turbidity.getActualValue();
                data.put("turbidityValue", turbidity.getActualValue() == null ? "" : turbidityValue.toString());
                BigDecimal turbidityValuePre = turbidity.getCalculatedValue();
                data.put("turbidityValuePre", turbidity.getCalculatedValue() == null ? "" : turbidityValuePre.toString());
            }
            dataList.add(data);
            currentTime = DateUtil.offsetMinute(currentTime, 2);
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值