springboot 本地/minio 附件下载优化

news/2024/5/16 21:21:20/文章来源:https://blog.csdn.net/zhanghuaiyu_35/article/details/130999922

文章目录

  • 前言
  • 一、Direct buffer memory
    • 1.1 原因分析
    • 1.2 解决方案
  • 二、附件下载
    • 2.1 问题分析
    • 2.2 解决方案
      • 2.2.1 本地下载
      • 2.2.1 minio下载


前言

  1. 本地上传大文件内存溢出 Direct buffer memory
  2. 附件下载服务端传流给前端需要将流缓存完毕才可以下载,导致大文件下载系统崩溃

一、Direct buffer memory

后端服务采用nio本地上传到服务器指定目录,通过nginx代理提供下载

1.1 原因分析

Java8出现了NIO,缓存,通道,选择器。在 写NIO程序的时候,经常使用ByteBuffer来读或者写入数据,这是一种基于通道(
Channel)与缓冲区( Buffer)的I/0方式.它可以使用 Native函数库直接分配堆外内存,然后通过一个存做在Java里面的
DirectByteBuffer对作为这块内存的引用进行操作。可以提高性能,因为避免了在Java堆和 Native堆中来回复制数据。
ByteBuffer. allocate(capability)第一种方式是分配java堆内存,属于GC管理范围,由于需要进行拷贝,所以比较慢。
ByteBuffer. allocteDirect (capability)第一种方式是分配操作系统的本地内存,不属于GC管辖范围,由于不需要内存拷贝所以速度相对较快。但如果不断分配本地内存,堆内存很少使用,那么java虚拟机就不需要进行GC,
DirectByteBuffer对象们就不会被回收,这个时候堆内存充足,但本地内存可能已经使用光了,在尝试分配本地内存就会出0ut0fMemory
Error,那程序就直接奔溃了。

linux 清理内存命令echo 1 > /proc/sys/vm/drop_caches

1.2 解决方案

采用慎用nio,特别是对大数据流场景,这里改用普通io操作数据流(后续引发问题分析)

二、附件下载

2.1 问题分析

无论是本地下载还是minio下载都存在一个隐形问题。
前端blog请求后,要等服务端将整个附件流传输完毕后才可以下载,对大文件(600M)不友好,大概率卡死。
F12 可以看到接口响应的大小一直在上升,直到整个文件传输完毕浏览器才会响应。
F12 可以看到
我们可以看到互联网下载都是在浏览器下载管理器下载,那么我们如何实现?
在这里插入图片描述
实际上本地下载我们通过nginx代理后的地址可以直接访问文件地址进行下载,满足上述要求。但是这样的操作会导致附件下载绕过后端直接请求,无法防止盗链。minio上传无法通过nginx实现(不考虑下载到服务器nginx代理,这样不合理)。

2.2 解决方案

2.2.1 本地下载

nginx + 重定向X-Accel-Redirect
这个功能允许你在后端处理权限,日志或任何你想干的,Nginx提供内容服务给终端用户从重定向后的路径,因此可以释放后端去处理其他请求(直接由Nginx提供IO,而不是后端服务)。这个功能类似 X-Sendfile 。

具体步骤篇幅太长请移步链接

2.2.1 minio下载

  1. minio管理界面可以截取到下载路径,模拟他的下载即可

  2. 连接地址发现需要传入minio的登录token,下一步想办法获取token

  3. 高版本支持多用户,可创建临时用户获取token(8.4.3)

  4. 高版本管理界面下载路径变了,【minio ip port】+/api/v1/buckets/+【bucket】+/objects/download?prefix=【Base64.*encode(附件路径)】+\&token=* + *token*

  5. 直接访问上一步的url即可下载

    https://github.com/minio/minio-java/tree/release/examples

    public Credentials getCredentials() {int durationSeconds = 360000;//秒//创建签名对象AssumeRoleProvider provider = new AssumeRoleProvider(properties.getUrl(),properties.getAccessKey(),properties.getSecretKey(),durationSeconds,//默认3600秒失效,设置小于这个就是3600,大于3600就实际值"{\n" +" \"Version\": \"2012-10-17\",\n" +" \"Statement\": [\n" +"  {\n" +"   \"Effect\": \"Allow\",\n" +"   \"Action\": [\n" +"    \"s3:GetObject\",\n" +"    \"s3:GetBucketLocation\",\n" +"    \"s3:PutObject\"\n" +"   ],\n" +"   \"Resource\": [\n" +"    \"arn:aws:s3:::test/*\"\n" +"   ]\n" +"  }\n" +" ]\n" +"}",properties.getRegion(),"arn:aws:s3:::*/*","anysession",null,null);Credentials credentials = provider.fetch();return credentials;}
    public String downloadByLink(HttpServletRequest request, HttpServletResponse response, String fileId) {AttachmentPO po = attachmentService.findById(fileId);Credentials credentials = minioTemplate.getCredentials();String token = credentials.sessionToken();//为了统一前端访问路径,直接查客户端请求Referer minio是前端ng代理的minio实际访问String referer = request.getHeader("Referer");String url = referer + "minio/api/v1/buckets/" + po.getClientId() + "/objects/download?prefix=" + Base64.encode(po.getPath()) + "&token=" + token;return url;}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_688095.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL第三章、表的增删查改

目录 一、CRUD 二、新增(Create) 2.1单行数据 全列插入 ​2.2多行数据 指定列插入 ​编辑 三、查询(Retrieve) ​3.1全列查询 3.2指定列查询 3.3 查询字段为表达式 3.4 别名 3.5 去重:DISTINCT 3.6 排序…

重磅新品 | 立仪发布高速版嵌入式光谱共焦G系列

重磅新品 | 立仪发布高速版嵌入式光谱共焦G系列 立仪科技作为国产光谱共焦技术的引领者,在光谱共焦技术上数年磨一剑,打破封锁,而此次研发出的嵌入式光谱共焦位移传感器G系列采用先进的FPGACPU硬件架构等技术自研而成并结合高强度LED光源、创…

chatgpt赋能python:Python编写抽奖程序——让你的活动更加有趣

Python编写抽奖程序——让你的活动更加有趣 在现代社会中,抽奖活动已经成为了许多商家和组织吸引关注、增强互动的重要手段。而使用Python编写抽奖程序可以帮助我们更加方便地进行这一活动。本文将介绍Python编写抽奖程序的方法,以及如何在实际应用中优…

chatgpt赋能python:如何用Python编写抽奖程序

如何用Python编写抽奖程序 抽奖活动是很多企业和组织引发用户关注和参与的一种有效手段。而Python作为一种简单易学,功能强大,受欢迎的编程语言,它可以很好地帮助我们实现抽奖程序的编写。本篇文章将介绍如何用Python编写抽奖程序&#xff0…

开发软件必须写代码?来看smardaten如何零代码开发学生管理系统

一、前言 互联网产品在我们的生活中无处不在,但你知道开发一个这样的产品需要的成本有多大吗? 传统的产品研发模式是:功能需求,需要调研,画原型,开发,测试,上线,跟踪运…

SpringBoot项目整合Redis作为缓存中间件的详细步骤

SpringBoot项目整合Redis作为缓存中间件的详细步骤 1.链接2.整合步骤3.测试Demo4.遇到的问题5.待考虑问题 有更好的建议,欢迎评论区留言~ 有不详细或者不准确的地方,欢迎评论区指正~ 有技术群嘛 hahh 可以拉我么 ~ 1.链接 哔哩教程视频 Redis官方 2.整…

区间预测 | MATLAB实现基于QRCNN-BiLSTM-Multihead-Attention卷积神经网络结合双向长短期记忆神经网络多变量时间序列区间预测

区间预测 | MATLAB实现QRCNN-BiLSTM-Multihead-Attention卷积神经网络结合双向长短期记忆神经网络多变量时间序列区间预测 目录 区间预测 | MATLAB实现QRCNN-BiLSTM-Multihead-Attention卷积神经网络结合双向长短期记忆神经网络多变量时间序列区间预测效果一览基本介绍模型描述…

哔哩哔哩视频云画质与窄带高清AI落地实践

视频赛道卷到下半场,一定会面临体验与成本的对抗,尤其是在行业大环境“过冬”的背景下,想要在有限带宽下获得最佳的画质观感变得异常具备挑战性。从视频云业务场景的视角来看,如何有效解决cross-domain问题、如何突破低业务延迟下…

蓝桥杯单片机PCF8591芯片ADC与DAC运行冲突解决

单片机型号:STC15F2K60S2 目录 文章附上工程下载地址: 在进行ADC与DAC测试时发现了如下冲突: 实验问题发现: 解决方案: 文章附上工程下载地址: https://download.csdn.net/download/qq_64257614/87854…

总结了几百个ChatGPT模型的调教经验,确定不来看看?

目录 前言 chatgpt调教指南 提示词 1.清晰的问题或请求: 2.上下文设置: 3.具体的主题或领域: 4.陈述性问题: 5.追问和澄清: 6.限定问题范围: 角色扮演 充当 Linux 终端 担任产品经理 充当 SQL…

chatgpt赋能python:使用Python编写数据接口:如何让您的网站更具吸引力和效率

使用Python编写数据接口:如何让您的网站更具吸引力和效率 在当今数字时代,大多数公司都希望能够从用户生成的数据中收集和分析信息,以了解他们的客户群体并提高他们的营销策略。为此,开发数据接口成为了一项对于互联网公司不可或…

Java程序设计入门教程 -- 一维数组

目录 一维数组创建 1.声明数组 2.分配数组内存空间 3.数组元素访问 数组初始化 1.静态初始化 2.动态初始化 一维数组的拷贝 1.数组元素的拷贝 2.数组名的拷贝 一维数组创建 1.声明数组 声明一个一维数组的方法很简单,格式如下: 数据类型名[ ] …

茅塞顿开的C#代码——通用型科学计算器

计算器是经常遇到的编程作业。 一般都是实现加、减、乘、除四则运算的普通计算器。 这里介绍用几十行C#代码实现的复杂的《科学计算器》,可以计算各种函数。 不知道其他语言实现同样的功能需要编写多少行代码?20000行? using System; usin…

Linux LNMP(Linux NGINX MySQL PHP)

NGINX处理静态页面性能出色,但是动态页面几乎没有处理能力,比Apache还差 所以涉及动态页面的场合一般由PHP Python Java(后缀php,py,jsp)等处理 静态页面请求 客户端 -> nginx动态页面请求 …

《水经注地图服务》下载与安装步骤

概述 《水经注地图服务》(WeServer)是一款可快速发布全国乃至全球海量卫星影像的地图发布服务产品,该产品完全遵循OGC相关协议标准,是一个基于若干项目成功经验总结的产品。它可以轻松发布100TB级海量卫星影像,从而使…

chatgpt赋能python:Python几次方介绍

Python几次方介绍 Python是一种通用编程语言,具有快速开发和易于阅读的优点。Python具有各种强大的功能,包括能够计算数值的能力。本文将介绍Python几次方的相关知识。 Python几次方的语法 要在Python中进行几次方运算,可以使用双星号&…

亚马逊云科技与涂鸦智能持续赋能开发者,推动全行业的数智化创新

近几年,智能产品已渗透至人们生活的方方面面,IoT技术市场规模也随之获得较快增长,据IoT Analytics的数据,2023年IoT市场规模将增长19%,或成为经济波动周期的一大黑马赛道,但下游应用场景与需求的高度碎片化…

chatgpt赋能python:Python利用数据可视化出图,为SEO拓展新思路

Python利用数据可视化出图,为SEO拓展新思路 数据可视化出图在SEO领域中是非常重要的,它不仅能丰富网站内容,还能提高用户体验。而Python语言在数据处理和可视化方面具有很大的优势,让我们一起来看看如何利用Python出图来拓展SEO应…

使用chartgtp写Android代码

<LinearLayout android:layout_width"match_parent" android:layout_height"match_parent" android:orientation"horizontal"> <TextView android:id"id/姓名" …

第三章 JVM内存概述

附录&#xff1a;精选面试题 Q&#xff1a;为什么虚拟机必须保证一个类的Clinit( )方法在多线程的情况下被同步加锁 &#xff1f; A: 因为虚拟机在加载完一个类之后直接把这个类放到本地内存的方法区&#xff08;也叫原空间&#xff09;中了&#xff0c;当其他程序再来调这个类…