蕲春网站建设,北京做网站推广seo,合肥市城乡建设局2019网站,做奢侈品网站有哪些文章目录1.实战背景2.问题描述3.问题分析4.问题解决1.实战背景
最近在做一个项目#xff0c;需要用到minio来搭建文件系统#xff0c;先简单说一下我在项目中设置的上传文件流程#xff1a;
前端将分块文件逐一传给后端#xff0c;后端再存储到 linux服务器的minio 当中。…
文章目录1.实战背景2.问题描述3.问题分析4.问题解决1.实战背景
最近在做一个项目需要用到minio来搭建文件系统先简单说一下我在项目中设置的上传文件流程
前端将分块文件逐一传给后端后端再存储到 linux服务器的minio 当中。所有分块文件存储完毕后端从 minio 下载所有的分块文件到本地磁盘中。后端进行合并文件处理将合并后的文件通过上传到minioSDK-Minio Java Client有自带分块上传方法
我在当前的项目开发阶段java后端服务是直接在本地进行运行而minio服务则是在购买的轻量服务器中运行。
2.问题描述
在上传文件流程的过程二中我发现一个2MB的分块文件下载到本地磁盘需要两到三秒而一个大文件肯定会有许多分块文件这就导致了当前端向后端发送合并文件请求后端需要花费大量的时间来处理主要就是花费在了从Minio下载分块文件到本地磁盘上。
一方面导致前端请求超时无法获取到后端的处理后结果。另一方面长时间的等待后端处理严重影响了用户的体验。 3.问题分析
1️⃣ 首先我怀疑是使用的服务器本身性能的问题于是又换了一个新的服务器6Mbps宽带用来只运行minio服务然后发现没卵用分块文件下载到本地速度还是一样慢。
2️⃣ 然后我做了许多的demo来进行下载测试在这里我给出比较有代表性的测试案例
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactIdversion2.6.3/version
/dependency
dependencygroupIdio.minio/groupIdartifactIdminio/artifactIdversion8.3.0/version
/dependency
dependencygroupIdme.tongfei/groupIdartifactIdprogressbar/artifactIdversion0.5.3/version
/dependency
dependencygroupIdcom.squareup.okhttp3/groupIdartifactIdokhttp/artifactIdversion4.8.1/version
/dependencyimport io.minio.GetObjectArgs;
import io.minio.MinioClient;
import org.apache.tomcat.util.http.fileupload.IOUtils;import java.io.FileOutputStream;
import java.io.InputStream;/*** author 狐狸半面添* create 2023-02-11 3:47*/
public class MinioFileDownLoadTest {private final static MinioClient minioClient;static {minioClient MinioClient.builder()// 指定连接的ip和端口轻量服务器.endpoint(http://1.14.94.100:9000)// 指定 访问秘钥也称用户id 和 私有秘钥也称密码.credentials(admin, 12345678).build();}public static void main(String[] args) throws Exception {// 平均用时14036mstest01();}public static void test01() throws Exception {Long start System.currentTimeMillis();// 拿到输入流我存放在minio的该文件为 10.1 MB 大小InputStream inputStream minioClient.getObject(GetObjectArgs.builder().bucket(waveedu).object(林屿森LIN - 小幸运【吉他】 (伴奏).mp3).build());// 拿到输出流用于下载到本地命名为 lucky.mp3FileOutputStream outputStream new FileOutputStream(D:\\lucky.mp3);// 用于拷贝流IOUtils.copy(inputStream, outputStream);Long end System.currentTimeMillis();System.out.println(用时 (end - start) ms);}
}test01()就是我在项目中使用的下载分块文件的方式。我进行了多次测试执行该方法可以看出确实很慢10.1MB的文件也要14秒左右。
于是小可爱的我换了一种下载方式 public static void test02() throws Exception {Long start System.currentTimeMillis();// 使用minio客户端提供的downloadObject方法进行下载minioClient.downloadObject(DownloadObjectArgs.builder()// 指定 bucket 存储桶.bucket(waveedu)// 指定 哪个文件.object(林屿森LIN - 小幸运【吉他】 (伴奏).mp3)// 指定存放位置与名称.filename(D:\\lucky.mp3).build());Long end System.currentTimeMillis();System.out.println(end - start);}我发现第一次执行该test02()方法下载的耗时和test01()的耗时一样但之后再执行test02()时发现都只需要0.2秒
于是我天真的以为就是不应该使用流拷贝的方式而是应该使用test02()的方式。但修改项目中的下载方式后几番折腾下来下载分块代码的时间和原来还是一样依旧2MB的分块文件下载到本地磁盘需要两到三秒。我真哭醉了。
3️⃣ 于是又几番demo测试和源码分析后我发现了为什么test02()第一次执行的耗时和test01()一样。
我们先看看 downloadObject 方法的对我们而言的关键源码 简单点说实际上就是 downloadObject 方法中也是使用流拷贝方式进行下载但在下载之前先会去判断 D:\lucky.mp3 是否已经在本地磁盘存在如果存在并且与minio中 waveedu 桶的文件 林屿森LIN - 小幸运【吉他】 (伴奏).mp3 所占字节大小一致就认为是相同文件没必要再从minio下载。因此第一次执行完test02()方法后之后再执行都是会直接判断出 fileSize stat.size()为true 就return了不会再流拷贝。
而我的test01()是没有走这个判断的不管本地指定位置存不存在都会进行流拷贝从minio下载文件。
4️⃣ 发现了不是项目所用的下载方法的原因后我开始思考是不是人品的问题于是进行反复无脑愚蠢的重启服务器和重启项目很显然没得屁用。
5️⃣ 再到最后我开始考虑是不是由于对轻量服务器是外网访问而导致传输速度很慢因此我依旧使用test01()的方法在我本地linux虚拟机中启动minio服务来测试下载速度
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import org.apache.tomcat.util.http.fileupload.IOUtils;import java.io.FileOutputStream;
import java.io.InputStream;/*** author 狐狸半面添* create 2023-02-11 15:10*/
public class NativeLinuxTest {public static void main(String[] args) throws Exception {MinioClient minioClient MinioClient.builder()// 指定连接的ip和端口该ip是本地虚拟机的虚拟Ip.endpoint(http://192.168.65.130:9000)// 指定 访问秘钥也称用户id 和 私有秘钥也称密码.credentials(minioadmin, minioadmin).build();Long start System.currentTimeMillis();// 拿到输入流我存放在minio的该文件为 10.1 MB 大小InputStream inputStream minioClient.getObject(GetObjectArgs.builder().bucket(waveedu).object(林屿森LIN - 小幸运【吉他】 (伴奏).mp3).build());// 拿到输出流用于下载到本地命名为 lucky.mp3FileOutputStream outputStream new FileOutputStream(D:\\lucky.mmp3);// 用于拷贝流IOUtils.copy(inputStream, outputStream);Long end System.currentTimeMillis();// 平均用时 0.2 到 0.3 秒System.out.println(用时 (end - start) ms);}
}可以看到每次调用该拷贝流的方法都是只需要 0.2 到 0.3 秒左右因此这也就证明了是由于后端项目启动在本地而minio服务放在了轻量服务器后端项目从minio下载文件必须外网访问的缘故。
4.问题解决
但这个问题在我们项目部署后肯定不存在的因为我们的项目也包括数据库、minio服务、redis服务肯定都是部署在同一局域网中如果项目不大的话简单点操作就是将所有服务放在一台服务器上。这样的好处就是可以极大的加快数据传输速率。