接口线上调用时间长排查

news/2025/1/20 9:38:45/

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

java">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的变量 {前缀.} 前缀可以区分不同的listInputStream 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导致时间花费太长

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

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

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

java">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);}

http://www.ppmy.cn/news/1503604.html

相关文章

揭秘智能工牌:如何成为房企销售团队的数字化转型加速器

在这个竞争激烈的市场环境中&#xff0c;房企想要脱颖而出&#xff0c;不仅需要优质的产品和服务&#xff0c;更需要高效的销售团队。而销售团队的能力提升&#xff0c;离不开精细化管理和科技的赋能。DuDuTalk智能语音工牌&#xff0c;正是这样一款融合了AI技术与销售实战智慧…

每天网安必用的Python解码神器

作者:郭震 解码URL编码的字符串 可以使用Python的urllib.parse模块.以下是一个完整的示例,展示了如何解码这段URL编码的字符串: import urllib.parse# 给定的URL编码字符串 encoded_url "%68%74%74%70%73%3A%2F%2F%76%31%31%2E%74%6C%6B%71%63%2E%63%6F%6D%2F%77%6A%76%3…

Vue Amazing UI:高颜值、高性能的前端组件库

Vue Amazing UI&#xff1a;高颜值、高性能的前端组件库 在当今前端开发中&#xff0c;Vue Amazing UI 作为一款功能强大的 UI 组件库&#xff0c;为开发者提供了全面的解决方案。本文将介绍 Vue Amazing UI 的基本信息、特点以及如何快速部署和使用。 软件简介 Vue Amazing U…

SCI中四区,计算机选题

借助元启发式算法训练xxxxx的强化学习融合红外和可见光图像 一种基于深度强化学习的动态路xxxxx宽的软件定义网络 xxxxxxx负矩阵分解的高效网络聚类方法 改进雾计算基础设xxxxxxx衡的混合元启发式算法 利用量子计算xxxxxxx物联网设备的新型数字电路

java实现加水印功能

1-Word加水印 实现原理&#xff1a; ● 通过页眉页脚生成文字水印或图片水印&#xff0c;然后设置页眉页脚的高度以及旋转角度来设置水印。 源代码&#xff1a; 1、引入pom依赖 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml…

【AIGC】Llama-3 官方技术报告

Llama-3 技术报告&#xff08;中文翻译&#xff09; 欢迎关注【youcans的AGI学习笔记】原创作品 0. 简介 现代人工智能&#xff08;AI&#xff09;系统的核心驱动力来自于基础模型。 本文介绍了一组新的基础模型&#xff0c;称为 Llama 3。它是一个语言模型系列&#xff0c;原…

【Android】数据存储之SQLite数据库知识总结

文章目录 SQL数据类型创建表格删除表格修改表格 数据库管理器SQLiteDatabase数据库的创建与删除 SQLiteOpenHelper使用步骤新建数据库操作类增删改查方法使用 SQLite 数据库版本更新 相关知识点ContentValues 类Cursor SQL SQL本质上是一种编程语言&#xff0c;它的学名叫作&qu…

群晖NAS结合内网穿透工具实现远程连接内网SFTP服务传输文件

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…