springboot 本地/minio 附件下载优化

这篇具有很好参考价值的文章主要介绍了springboot 本地/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 问题分析

告别Direct buffer memory的后续问题
无论是本地下载还是minio下载都存在一个隐形问题。
前端blog请求后,要等服务端将整个附件流传输完毕后才可以下载,对大文件(600M)不友好,大概率卡死。
F12 可以看到接口响应的大小一直在上升,直到整个文件传输完毕浏览器才会响应。
springboot 本地/minio 附件下载优化
我们可以看到互联网下载都是在浏览器下载管理器下载,那么我们如何实现?
springboot 本地/minio 附件下载优化
实际上本地下载我们通过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;
    }

springboot 本地/minio 附件下载优化文章来源地址https://www.toymoban.com/news/detail-468665.html

到了这里,关于springboot 本地/minio 附件下载优化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot+MinIO 实现文件上传、读取、下载、删除

    一、 MinIO 二、 MinIO安装和启动 三、 pom.xml 四、 applicatin.properties(配置文件) 五、 编写Java业务类

    2024年02月09日
    浏览(47)
  • SpringBoot整合minio,文件的上传下载,批量获取

    Minio是GlusterFS创始人之一Anand Babu Periasamy发布新的开源项目。基于Apache License v2.0开源协议的对象存储项目,采用Golang实现,客户端支Java,Python,Javacript, Golang语言。 其设计的主要目标是作为私有云对象存储的标准方案。主要用于存储海量的图片,视频,文档等。非常适合于存储

    2024年02月12日
    浏览(48)
  • 【Java】对Minio指定Bucket大量文件的批量下载与本地文件夹的批量上传

    需要批量下载一个bucket下的内容,bucket下文件有19GB+,且文件夹结构复杂,使用官方的Console无法完成这么大量文件的下载,而且也不支持文件夹的分享,所以自己写个工具下载,顺便把上传的也写了。 使用官方的打包下载,由于文件太多,一直转,而且session一失效,或者刷

    2024年02月09日
    浏览(56)
  • Springboot+Minio通过分片下载解决IOS下H5无法播放视频问题

    一、环境说明 JDK 1.8 Springboot 2.7.5 Minio 8.4.5 Vue3实现的微信公众号网页 二、问题描述 当前项目是基于springboot和vue3的前后端分离架构,前端目前主要是基于H5展示在微信公众号的网页中。在实现视频上传、在线播放时遇到问题:前端同事说苹果手机播放不了视频,刚开始是统一

    2024年02月11日
    浏览(82)
  • C# MVC controller 上传附件及下载附件(笔记)

    描述:Microsoft.AspNetCore.Http.IFormFileCollection 实现附件快速上传功能代码。 上传附件代码 upLoadFile Model类定义 附件下载代码:

    2024年02月13日
    浏览(50)
  • 附件展示 点击下载

    效果图   实现代码

    2024年02月14日
    浏览(38)
  • 小程序附件下载并预览功能

    一、实现的功能: 1、word、excel、图片等实现下载并预览 2、打开文件后显示文件名称 二、代码:

    2024年02月15日
    浏览(38)
  • AbstractHttpMessageConverter + easyexcell优雅下载附件

    AbstractHttpMessageConverter 是 Spring 框架中用于处理 HTTP 消息转换的抽象基类。它用于处理来自 HTTP 请求的消息,并将其转换为特定的 Java 对象,或者将 Java 对象转换为 HTTP 响应消息。 这个抽象类允许开发人员创建自定义的 HTTP 消息转换器,以便在 Spring MVC 或 Spring WebFlux 应用程序

    2024年01月20日
    浏览(25)
  • Spring Boot学习随笔- 文件上传和下载(在线打开、附件下载、MultipartFile)

    学习视频:【编程不良人】2021年SpringBoot最新最全教程 文件上传是指将文件从客户端计算机传输到服务器的过程。 上传思路 前端的上传页面:提交方式必须为 post , enctype 属性必须为 multipart/form-data 开发后端的Controller 后端方法接收参数必须和前端标签的name名一致 upload.js

    2024年02月04日
    浏览(40)
  • 大文件下载优化方案(nginx+Springboot+vue)---非常完美

    1、背景: 系统中有个文件下载的功能,下载的文件从1k-几十G不等,小文件下载没有问题,只要上G了,下载大概率失败。基于以上现状,对技术方案记性优化。 2、历史方案: 2.1 服务器读取文件流传输+前端blob接收 描述: 后端接口通过response的IO通道,读写文件流传输 前端

    2024年02月16日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包