网站首页 > 编程文章 正文
如何避免内存不足
介绍
这周,我和我的团队遇到了我在大学时第一次读到的一个问题。 自十月的星期三以来,我完全忘记了它:通过HTTP传输非常大的文件。
需求与设计
我们的客户将其CRM替换为一个云CRM,然后我们将其与整个软件地图集成在一起。
一个集成流程将文档从本地存储发布到CRM,并将其与存储的客户账户关联; 文件大小没有上限,我们假设1 GB为中值。
所有CRM集成均基于REST,不允许共享文件夹,暂存数据库,仅允许受保护的REST API OAUTH1。
我在下图中为您绘制了一个简化的建筑模型。
我们的应用程序与应用程序映射的其他部分一样,在CRM托管在云租户上的前提下在前提环境中运行。
公开的API接受包含两部分的Multipart主体:一个包含包含元数据(如文件名,客户帐户ID等)的JSON文档,另一个则包含文件的二进制内容。
标准解决方案
该应用程序由两部分组成:第一部分是文件轮询器,该轮询器每次在临时文件夹中看到一个新文件时都会创建一个线程,而第二部分将其与客户账户相关联并发送给CRM。
如果您有兴趣创建文件轮询器,可以将Apache Camel Polling Consumer链接到您,这是轻松实现的绝佳解决方案。
在此,我有兴趣与您讨论我们将文件发送到CRM的方式。
让我们开始编码; 这是pom.xml的摘录:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
这里我们的标准解决方案代码是
RestTemplate remoteService = new RestTemplate();
//HTTP has two parts: Header and Body
//Here is the header:
HttpHeader header = new HttpHeader();
//Here is the body
MultiValueMap<String,Object> bodyMap = new MultiValueMap<String,Object>();
bodyMap.add(“customer_file”,new FileSystemResource(fileName));
bodyMap.add(“customer_name”, customerJSON);
HttpEntity<MultiValueMap> request = new HttpEntity(bodyMap, header);
ResponseEntity<String> restResponse = remoteService .exchange(remoteServiceURL, HttpMethod.POST, request, String);
customerJson变量是javax.json.JsonObject; 这样,多部分请求就可以自主选择正确的内容类型,并且在使用
org.springframework.core.io.FileSystemResource实例时,可以期待相同的行为。
我们做了这些测试:
· 发送一个小文件以查找一些格式错误的请求
· 发送一个巨大的文件证明我们的应用程序健壮性
对于本文来说,测试1并没有什么重要的问题,缺少一些标头值,错误的URL格式输入等等。测试2使得我们等待了几分钟,然后所有Java开发人员的噩梦都蒙上了阴影。
java.lang.OutOfMemoryError: Java heap space
出现此问题的原因不仅是因为我们在开发环境中运行了代码,还因为该应用程序试图将整个文件内容加载到内存中,从而使它比J. Wellington Wimpy占用更多的内存。
很清楚,分析应用程序的内存占用量,简单性和简单性。
回顾一下,从架构的角度来看,这也不是一个很好的解决方案,因为:
· 我们无法假设传入文件的最大大小
· 我们无法按顺序处理文件
我们需要改进它。
分块解决方案
我们需要的是修改我们的代码,而不是将整个文件内容加载到内存中,而是使用HTTP1.1支持的功能,直到我上大学的时候:分块传输编码。
此功能告诉服务器传入请求是由多个HTTP消息组成的,它需要接收所有HTTP消息才能开始处理。
从客户端的角度来看,优点在于您仅将当前正在传输的切片加载到内存中。
如果您想进一步了解HTTP如何实现分块传输编码,请遵循WIKI,W3C。
我们改进了正确配置RestTemplate的类:
RestTemplate remoteService = new RestTemplate();
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
remoteService.setRequestFactory(requestFactory);
我们重复了测试2,这次运行顺利。
对于1.5 GB文件的完整传输,我们发现内存占用不足300 MB! 成功!
结论
在本文中,我描述了我们发现的传输大型文件的解决方案。 您可以使用不同的库找到多个其他库。
我想补充一点,此功能仅与HTTP1.1一起提供,并且HTTP 2不再支持分块传输编码。 我认为您必须寻找某种流API。
在这里,我们选择使用众所周知的RestTemplate类,而不是较新的WebClient:我无法告诉您是否可以适应它。
最后,我要感谢Luca和Davide在制定完整解决方案上所花费的时间,这些时间启发了本文,当然也感谢我们每天的所有笑声。
(本文翻译自Simone Maletta的文章《Transfer Large Files Using a Rest API》,参考:
https://medium.com/swlh/transfer-large-files-using-a-rest-api-a0aa96983ebb?source=
topic_page---------13------------------1----------)
猜你喜欢
- 2025-06-10 速看!DeepSeek携手Kimi,解锁图文报表智能生成黑科技
- 2025-06-10 SpringBoot2调用第三方接口时,考虑异常处理、安全性和超时重试
- 2025-06-10 100个Java工具类之6:用4种方式发起HTTP请求
- 2024-08-12 Java Web之HttpClient请求连接池连接池
- 2024-08-12 接口测试02(接口测试的目的)
- 2024-08-12 排名前 16 的 Java 工具类,哪个你没用过?
- 2024-08-12 Java程序员常用的16个Java实用工具类
- 2024-08-12 接口测试03(接口测试怎么测)
- 2024-08-12 Java发送http请求(java http post请求)
- 2024-08-12 深入Spring Boot 2:使用HttpClient发起网络请求的艺术
你 发表评论:
欢迎- 最近发表
-
- 「完结13章」Python+Vue 全栈开发BI数据可视化项目
- 为什么前端要学JavaScript?JS都有哪些逆天的功能?
- 可视化大屏设计秘籍:功能布局配色全方位解读,新手也能轻松上手
- 5个常用的canvas/js数据可视化库推荐
- LPL比赛数据可视化,完成这个项目,用尽了我的所有Python知识
- Wincc如何通过OPC连接实现数据接入
- OPC Router中央通信平台软件协助打造高度智能化物流港口
- Tyler, The Creator《CALL ME IF YOU GET LOST》:贴近生活的不定与禁忌
- 首首经典!英国歌手John Waite作品If You Ever Get Lonely
- Talks with China will not materialize if the White House expects all get no give
- 标签列表
-
- spire.doc (70)
- system.data.oracleclient (61)
- 按键小精灵源码提取 (66)
- pyqt5designer教程 (65)
- 联想刷bios工具 (66)
- c#源码 (64)
- graphics.h头文件 (62)
- mysqldump下载 (66)
- sqljdbc4.jar下载 (56)
- libmp3lame (60)
- maven3.3.9 (63)
- 二调符号库 (57)
- 苹果ios字体下载 (56)
- git.exe下载 (68)
- diskgenius_winpe (72)
- pythoncrc16 (57)
- solidworks宏文件下载 (59)
- qt帮助文档中文版 (73)
- satacontroller (66)
- hgcad (64)
- bootimg.exe (69)
- android-gif-drawable (62)
- axure9元件库免费下载 (57)
- libmysqlclient.so.18 (58)
- springbootdemo (64)
本文暂时没有评论,来添加一个吧(●'◡'●)