当前位置: 首页 > article >正文

Android调用springboot接口上传大字段,偶现接口超时的优化

介绍

最近有个功能,Android通过okhttp上传实体类,实体类包含一个大字段,上传的字符串长度达到300k,偶现接口超时的情况,大概100次有5次,看日志发现数据并没有到达接口,可能在网络传输中就超时了

优化1

​​直接接收对象:

    @ApiOperation(value = "插入主动测量记录")@PostMapping("/insertMeasureRecord")public Result insertMeasureRecord(@RequestBody LomeRingMeasureRecords lomeRingMeasureRecords ){return iRingAppService.insertMeasureRecord(lomeRingMeasureRecords);}

刚开始是这样接收的,后来优化成流式解析
流式解析:

  @Overridepublic Result insertMeasureRecordRequest(HttpServletRequest request) {// 1. 使用流式读取避免内存爆炸try (InputStream is = request.getInputStream();Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {// 2. 带超时的JSON解析CompletableFuture<LomeRingMeasureRecords> future = CompletableFuture.supplyAsync(() -> {return JSON.parseObject(reader, LomeRingMeasureRecords.class);});LomeRingMeasureRecords records = future.get(15, TimeUnit.SECONDS); // 15秒超时// 3. 继续原有处理逻辑return Result.ok(lomeRingMeasureRecordsService.insertMeasureRecords(records));} catch (TimeoutException e) {return Result.fail(ResultsCode.REQUEST_FAILED);} catch (Exception e) {return Result.fail(ResultsCode.REQUEST_FAILED);}}

优化2

即使修改成这样,还是偶现超时,所以对大字段进行了压缩,然后服务端进行解压
Android部分

public static Observable<JsonResult> insertMeasureRecord(String mac,String value,String testType,String filePath,String fileName,String label,String waveForm) {Log.i("waveForm size",waveForm.length()+"");String compressString="";try {compressString = DataCovertUtils.compressString(waveForm);} catch (IOException e) {e.printStackTrace();}Log.i("compressString size",compressString.length()+"");Map<String, Object> map = new HashMap<>();map.put("mac", mac);map.put("value", value);map.put("testType", testType);map.put("filePath", filePath);map.put("fileName", fileName);map.put("label", label);map.put("compressedWaveForm", compressString);return ServerAPIClient.getApi().insertMeasureRecord(map).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidScheduler.mainThread());}
  // GZIP压缩字符串public  static String compressString(String str) throws IOException {if (str == null || str.isEmpty()) {return str;}ByteArrayOutputStream out = new ByteArrayOutputStream();try (GZIPOutputStream gzip = new GZIPOutputStream(out)) {gzip.write(str.getBytes(StandardCharsets.UTF_8));}return Base64.encodeToString(out.toByteArray(), Base64.NO_WRAP);}

然后springboot解压

 @Overridepublic Result insertMeasureRecordRequest(HttpServletRequest request) {try (InputStream is = request.getInputStream();Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {LomeRingMeasureRecords records = JSON.parseObject(reader, LomeRingMeasureRecords.class);// 解压处理if (records.getCompressedWaveForm() != null ) {try {String decompressed = decompressString(records.getCompressedWaveForm());records.setWaveForm(decompressed);} catch (IOException e) {// 解压失败记录日志,保持原数据log.error("解压waveForm失败", e);return Result.fail(ResultsCode.REQUEST_FAILED);}}return Result.ok(lomeRingMeasureRecordsService.insertMeasureRecords(records));} catch (Exception e) {log.error("处理测量记录请求失败", e);return Result.fail(ResultsCode.REQUEST_FAILED);}}// GZIP解压字符串private String decompressString(String compressedStr) throws IOException {if (compressedStr == null || compressedStr.isEmpty()) {return compressedStr;}byte[] compressed = Base64.getDecoder().decode(compressedStr);ByteArrayInputStream bis = new ByteArrayInputStream(compressed);GZIPInputStream gis = new GZIPInputStream(bis);// 使用ByteArrayOutputStream直接读取所有字节ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len;while ((len = gis.read(buffer)) > 0) {baos.write(buffer, 0, len);}// 转换为字符串,保留原始换行符String result = baos.toString(StandardCharsets.UTF_8.name());gis.close();bis.close();baos.close();return result;}

这样原字段大概是300k,然后压缩完是55k,之前接口返回是3s,修改完是2.5s,因为涉及到python计算,没办法再提高了

疑问

按理说,字段没超过1M,不应该出现超时的情况,根本没有到达接口,可能还是网络问题

场景化建议

  1. ​​推荐使用​直接接收对象的场景​​
    字段大小​​<1MB​​且结构固定(如普通表单数据)。
    需要快速开发,减少手动编码量。
    服务端内存充足(如JVM堆内存>2GB)。
  2. ​​推荐使用流式解析的场景​​
    字段大小​​>10MB​​或包含压缩数据(如音频、视频、科学计算数据)。
    需要支持​​分片传输​​或​​断点续传​​(如大文件上传)。
    服务端内存受限(如云函数环境)

性能关键点分析

  1. ​​数据解析性能​​
    ​​方式1(对象绑定)​​:
    依赖Jackson或Gson等库的优化解析,实测1MB JSON数据解析耗时约​​5-20ms​​(Spring Boot默认配置)。
    ​​瓶颈​​:大字段(如10MB+)可能导致堆内存压力和GC停顿。
    ​​方式2(流式解析)​​:
    使用BufferedReader逐行读取或JSONReader流式解析,1MB数据耗时约​​2-8ms​​(分块处理减少内存峰值)。
    ​​优势​​:避免一次性加载大对象到内存,适合处理​​压缩数据流​​或​​分片传输​​场景。
  2. ​​内存与GC影响​​
    ​​方式1​​:
    若字段包含大文本或二进制数据(如压缩后的波形数据),可能直接导致​​堆内存溢出​​(默认堆大小约128MB-1GB)。
    ​​示例​​:10MB的compressedWaveForm字段会占用约​​20MB堆内存​​(含对象头和引用)。
    ​​方式2​​:
    流式处理可将内存占用控制在​​常量级别​​(如分块读取时每次仅加载64KB),适合处理​​超大数据流​​(如50MB+的压缩文件)
  3. ​​压缩数据处理​​
    ​​方式1的缺陷​​:
    若字段已压缩(如GZIP),直接反序列化会触发​​二次解压​​(框架先解压到临时文件或内存,再解析JSON),导致​​CPU和内存双重消耗​​。
    ​​实测​​:10MB GZIP数据全量解压后约25MB,解析耗时增加50%。
    ​​方式2的优化​​:
    可在流式解析中​​直接处理压缩流​​(如GZIPInputStream),避免中间数据存储,节省50%以上CPU和内存。

性能测试数据参考

在这里插入图片描述

相关文章:

Android调用springboot接口上传大字段,偶现接口超时的优化

介绍 最近有个功能&#xff0c;Android通过okhttp上传实体类&#xff0c;实体类包含一个大字段&#xff0c;上传的字符串长度达到300k&#xff0c;偶现接口超时的情况&#xff0c;大概100次有5次&#xff0c;看日志发现数据并没有到达接口&#xff0c;可能在网络传输中就超时了…...

在PyCharm中部署AI模型的完整指南

引言 随着人工智能技术的快速发展,越来越多的开发者开始将AI模型集成到他们的应用程序中。PyCharm作为一款强大的Python IDE,为AI开发提供了出色的支持。本文将详细介绍如何在PyCharm中部署AI模型,从环境配置到最终部署的完整流程。 第一部分:准备工作 1. 安装PyCharm …...

react组件之间如何使用接收到的className(封装一个按钮案例)

带有hover渐变效果 一、父组件 import LineGradientBox from ../line-gradient-box; import styles from ./index.module.scss;<LineGradientBoxfontSize{20}className{styles.btn_height}textSign upwidth"100%"onClick{() > {navigate(/sign-up);}} /> …...

JavaScript 数组常用方法解析

1. concat - 合并数组 语法&#xff1a; const newArray oldArray.concat(value1, value2, ..., arrayN); 作用&#xff1a; 将当前数组与其他数组或值合并&#xff0c;返回一个新数组&#xff0c;原数组不变。 测试案例&#xff1a; const arr1 [1, 2, 3]; const arr2…...

Linux知识--软件管理

1.RPM包 1.1简介 又称为二进制包&#xff0c;无需编译&#xff0c;可以直接使用 1.2工具 1.2.1YUM工具 简介 基于RPM包管理&#xff0c;能够从指定服务器自动下载RPM包并且安装 可以自动处理依赖关系&#xff0c;并且一次性安装所有依赖的软件包&#xff0c;无需一…...

09.传输层协议 ——— TCP协议

文章目录 TCP协议 谈谈可靠性TCP协议格式 序号与确认序号窗口大小六个标志位 确认应答机制&#xff08;ACK&#xff09;超时重传机制连接管理机制 三次握手四次挥手 流量控制滑动窗口拥塞控制延迟应答捎带应答面向字节流粘包问题TCP异常情况TCP小结基于TCP的应用层协议 TCP协…...

chromedp 反反爬设计方案

二、基础防护层实现 1. 浏览器特征伪装 opts : append(chromedp.DefaultExecAllocatorOptions[:],// 禁用自动化特征chromedp.Flag("disable-blink-features", "AutomationControlled"),chromedp.Flag("useAutomationExtension", false),// 随…...

数字化转型“变形记”:中钧科技经营帮如何让企业长出“智慧骨骼”

数字化转型就像给企业安装一个"智慧引擎"&#xff0c;而中钧科技的经营帮平台就是这台引擎的智能控制系统。让我们用"人体"来打个比方——当企业的数据、流程、决策像神经脉络般打通&#xff0c;才能真正实现灵活运转。下面就以经营帮的五大核心板块为例&a…...

【问题解决】centos7已经不维护了,如何继续使用yum源?

背景 CentOS 7 已于2024年6月30日停止维护&#xff0c;在停止维护后我们之前配置的国内镜像源大多都是空目录了&#xff0c;即在线国内镜像源不可用,就像下边这样提示&#xff1a; [rootbogon yum.repos.d]# yum install vim 已加载插件&#xff1a;fastestmirror Loading mi…...

Starrocks 数据均衡DiskAndTabletLoadReBalancer的实现

背景 最近在研究了一下 Starrocks的tablet的Rebalance的能力&#xff0c;这里进行记录一下 本文基于 StarRocks 3.3.5 结论 数据的rebalance 主要以两种模式来进行&#xff1a; 按照磁盘的使用率进行移动&#xff0c;如果每个BE的磁盘使用率不足tablet_sched_balance_load_…...

Redis 接收连接

阅读本文前&#xff0c;建议先看&#xff1a;Redis 事件循环&#xff08;Event Loop&#xff09;。 Redis 6 支持接收 3 种连接&#xff0c;对应的接收处理器如下&#xff1a; TCP&#xff1a;acceptTcpHandler&#xff1b;TLS&#xff1a;acceptTLSHandler&#xff1b;Unix …...

AGI大模型(12):向量检索之关键字搜索

1 检索的方式有那些 列举两种: 关键字搜索:通过用户输入的关键字来查找文本数据。语义搜索:不仅考虑关键词的匹配,还考虑词汇之间的语义关系,以提供更准确的搜索结果。2 关键字搜索 先看一个最基础的实现 安装模块 pip install redis 不会redis的去看我的redis专题 首…...

【计算机视觉】CV实战项目- Face-and-Emotion-Recognition 人脸情绪识别

Face-and-Emotion-Recognition 项目详细介绍 项目概述项目功能项目目录结构项目运行方式1. 环境准备2. 数据准备3. 模型训练4. 模型运行 常见问题及解决方法1. **安装依赖问题**2. **数据集问题**3. **模型训练问题**4. **模型运行问题** 项目实战建议项目参考文献 项目概述 F…...

基于国产 FPGA+ 龙芯2K1000处理器+翼辉国产操作系统继电保护装置测试装备解决方案

0 引言 近年来&#xff0c;我国自主可控芯片在国家政策和政 府的支持下发展迅速&#xff0c;并在电力、军工、机械、 通信、电子、医疗等领域掀起了国产化替代之 风&#xff0c;但在芯片自主可控和国产化替代方面还有明 显的不足之处。 2022年我国集成电路进口量多 达 5 3…...

如何批量为多个 Word 文档添加水印保护

在日常办公中&#xff0c;Word文档添加水印是一项重要的操作&#xff0c;特别是在需要保护文件内容的安全性和版权时。虽然Office自带了添加水印的功能&#xff0c;但当需要一次性给多个Word文档添加水印时&#xff0c;手动操作显得非常繁琐且低效。为了提高效率&#xff0c;可…...

Qt QThread 两种线程管理方法

在 Qt 中,QThread 有两种常见的用法,分别对应不同的线程管理模型。这两种方法各有优缺点,适用于不同的场景: 1. 子类化 QThread(继承 QThread,重写 run() 方法) 这是传统的线程用法,类似于 Java 或 C++ 标准库中的线程模型。通过继承 QThread 并重写 run() 方法,将需…...

长期行为序列建模技术演进:从SIM到TWIN-v2

背景 在推荐系统与广告投放领域&#xff0c;长期行为序列建模旨在从用户数月甚至数年的历史行为中捕捉稳定兴趣模式&#xff0c;是解决冷启动、提升推荐精度的关键。随着工业界需求激增&#xff0c;SIM、ETA、SDIM、TWIN及TWIN-v2等模型相继诞生&#xff0c;推动技术不断革新。…...

Linux下 REEF3D及DIVEMesh 源码编译安装及使用

目录 软件介绍 基本依赖 一、源码下载 1、REEF3D 2、DIVEMesh 二、解压缩 三、编译安装 1、REEF3D 2、DIVEMesh 四、算例测试 软件介绍 REEF3D是一款开源流体动力学框架&#xff0c;提供计算流体力学及波浪模型。软件采用高效并行化设计&#xff0c;可以在大规模处理器…...

极狐GitLab Git LFS 速率限制如何设置?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 Git LFS 速率限制 (BASIC SELF) Git LFS (Large File Storage) 是一个用于处理大文件的Git扩展。如果您在仓库中使用 Git LF…...

缓存,内存,本地缓存等辨析

快速辨析缓存&#xff0c;内存&#xff0c;本地缓存&#xff0c;memcache&#xff0c;redis等 &#xff08;个人临时记录&#xff09; 缓存 泛指所有用于暂存数据以提升访问速度的技术&#xff0c;包括本地缓存、分布式缓存、CPU缓存等。核心目标是减少对慢速存储&#xff08…...

【k8s】PV,PVC的回收策略——return、recycle、delete

PV 和 PVC 的回收策略主要用于管理存储资源的生命周期&#xff0c;特别是当 PVC 被删除时&#xff0c;PV 的处理方式。回收策略决定了 PV 在 PVC 被删除后的行为。 回收策略的类型 Kubernetes 提供了三种主要的回收策略&#xff0c;用于管理 PV 的生命周期&#xff1a; Reta…...

YOLO算法的革命性升级:深度解析Repulsion损失函数在目标检测中的创新应用

## 一、目标检测的痛点与YOLO的局限性 在自动驾驶、智能监控等复杂场景中,目标检测算法常面临致命挑战——遮挡问题。当多个物体相互遮挡时,传统检测器容易出现漏检、误检现象,YOLO系列算法尽管在速度与精度上表现优异,但在处理密集遮挡目标时仍存在明显短板。 ### 1.1 遮…...

嵌入式软件测试的革新:如何用深度集成工具破解效率与安全的双重困局?

在汽车电子、工业控制、航空航天等嵌入式开发领域&#xff0c;团队常面临一个看似无解的悖论&#xff1a;如何在保证代码安全性的前提下&#xff0c;大幅提升测试效率&#xff1f; 传统测试工具往往需要搭建独立环境、插入大量桩代码&#xff0c;甚至需要开发者手动编写测试用例…...

Android studio—socketIO库return与emit的使用

文章目录 一、Socket.IO库简单使用说明1. 后端 Flask Flask-SocketIO2. Android 客户端集成 Socket.IO3. 布局文件注意事项 二、接受服务器消息的二种方法1. 客户端接收通过 emit 发送的消息功能使用场景后端代码&#xff08;Flask-SocketIO&#xff09;客户端代码&#xff08…...

【Python进阶】VSCode Python开发完全指南:从环境配置到高效调试

目录 前言技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比 二、实战演示环境配置要求核心代码实现案例1&#xff1a;配置虚拟环境案例2&#xff1a;智能代码补全案例3&#xff1a;调试配置 运行结果…...

验证Kubernetes的服务发现机制

验证Kubernetes的服务发现机制 文章目录 验证Kubernetes的服务发现机制[toc]一、验证基于环境变量的服务发现机制 服务发现是让客户端能够以固定的方式获取到后端Pod访问地址的机制。下面验证环境变量和DNS这两种机制。 一、验证基于环境变量的服务发现机制 对于需要访问服务…...

《计算机视觉度量:从特征描述到深度学习》—深度学习图像特征工程

传统算法的图像特征分析和描述&#xff0c;一直贯穿图像算法的发展。2017年深度学习的出现&#xff0c;很多开发人员和技术人员认为&#xff0c;图像特征分析这个概念可以被深度学习完全取代。很长一段时间以深度学习为主的视觉方案成为主流&#xff0c;逐渐淡化了传统视觉的特…...

Ubuntu24.04安装ROS2问题

1&#xff0c;根据官方指导安装&#xff0c;安装到步骤&#xff1a; sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg 时遇到问题。导致sudo apt update一直报错&#xff1a; 找了几天的资料…...

【图问答】DeepSeek-VL 论文阅读笔记

《DeepSeek-VL: Towards Real-World Vision-Language Understanding》 1. 摘要/引言 基于图片问答&#xff08;Visual Question Answering&#xff0c;VQA&#xff09;的任务 2. 模型结构 和 三段式训练 1&#xff09;使用 SigLIP 和 SAM 作为混合的vision encoder&#xf…...

【专题刷题】滑动窗口(二):水果成篮,所有字母异位词,乘积小于 K 的子数组

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码&#xff1b;&#xff…...