珠海编程培训机构,宁波seo网络推广优化价格,ie建设企业网站进去无法显示,自己怎么做网站视频赚钱吗分布式文件系统 SpringBootFastDFSVue.js【一】 一、分布式文件系统1.1.文件系统1.2.什么是分布式文件系统1.3.分布式文件系统的出现1.3.主流的分布式文件系统1.4.分布式文件服务提供商1.4.1.阿里OSS1.4.2.七牛云存储1.4.3.百度云存储 二、fastDFS2.1.fastDSF介绍2.2.为什么要使… 分布式文件系统 SpringBootFastDFSVue.js【一】 一、分布式文件系统1.1.文件系统1.2.什么是分布式文件系统1.3.分布式文件系统的出现1.3.主流的分布式文件系统1.4.分布式文件服务提供商1.4.1.阿里OSS1.4.2.七牛云存储1.4.3.百度云存储 二、fastDFS2.1.fastDSF介绍2.2.为什么要使用fastDFS2.3.fastDSF工作原理2.3.1.fastDSF架构2.3.2.文件上传流程2.3.3.文件下载流程 三、fastDFS入门3.1.fastDFS安装与配置3.2.文件上传下载测试3.2.1.搭建环境3.2.1.1.创建maven工程3.2.1.2.添加依赖3.2.1.3.配置文件 3.2.2.文件上传3.2.2.1.文件上传代码实现3.2.2.2.运行结果3.2.2.3.测试上传结果-访问 3.2.3.文件查询3.2.3.1.文件查询代码实现3.2.3.2.运行结果 3.2.4.文件下载3.2.4.1.文件下载代码实现3.2.4.2.运行结果 3.2.5.文件删除3.2.5.1.文件删除代码实现3.2.5.2.运行结果3.2.5.3.服务器查看 3.3.recv body length: 70 is not correct, expect length: 403.3.1.解决问题修改依赖3.3.2.下载源码打包成jar包并上传到本地maven仓库3.3.2.1.下载解压3.3.2.2.使用maven从源码安装3.3.2.3.进入/target 目录执行CMD 命令将jar包打包到本地maven仓库3.3.2.4.在maven项目pom.xml中添加fastdfs-client-java依赖 四、文件服务案例4.1.目标使用fastDSF实现图片服务器4.2.需求分析4.3.功能开发4.3.1.搭建fastDFS文件服务器4.3.2.搭建文件管理服务4.3.2.1.添加依赖4.3.2.2.fastdfs-client配置文件4.3.2.3.跨域配置CrossConfig.java4.3.2.4.创建模型--实体类4.3.2.4.1.FileSystem.java4.3.2.4.2.Result.java 4.3.2.5.创建controller4.3.2.6.创建优化后的controller代码4.3.2.7.创建application.yml4.3.2.8.创建spring boot启动类 4.3.3.管理系统前端【Vue2】项目4.3.3.1.axios模块4.3.3.1.1.安装axios模块4.3.3.1.2.在入口文件main.js中配置axios4.3.3.1.3.axios使用案例4.3.3.1.4.vue-axios使用案例 4.3.3.2.关闭Vue的生产提示4.3.3.3.vue项目中无router文件夹vue安装路由4.3.3.4.引入Vue Router路由Vue.js【v.3x】4.3.3.5.引入ElementUI组件库【Vue2 版本】4.3.3.6.main.js完整版4.3.3.7.页面创建UploadImg.vue4.3.3.8.修改App.vue4.3.3.9.创建路由配置router/index.js4.3.3.10.课程图片浏览 4.3.4.管理系统前端【Vue3】项目4.3.4.1.axios模块4.3.4.1.1.安装axios模块4.3.4.1.2.在入口文件main.js中配置axios 4.3.4.2.关闭Vue的生产提示4.3.4.3.vue项目中无router文件夹vue安装路由4.3.4.4.引入Vue Router路由Vue.js【v.4x】4.3.4.5.引入Element Plus组件库【Vue3 版本】4.3.4.6.main.js完整版4.3.4.7.页面创建UploadImg.vue4.3.4.8.修改App.vue4.3.4.9.创建路由配置router/index.js4.3.4.10.页面效果 五、总结endl 一、分布式文件系统
1.1.文件系统
操作系统中负责管理和存储文件信息的软件机构称为文件管理系统简称文件系统。
常见的文件系统FAT16/FAT32、NTFS、HFS、UFS、APFS、XFS、Ext4等 。
1.2.什么是分布式文件系统
分布式文件系统Distributed File SystemDFS是指文件系统管理的物理存储资源不一定直接连接在本地节点上而是通过计算机网络与节点可简单的理解为一台计算机相连或是若干不同的逻辑磁盘分区或卷标组合在一起而形成的完整的有层次的文件系统。
DFS为分布在网络上任意位置的资源提供一个逻辑上的树形文件系统结构从而使用户访问分布在网络上的共享文件更加简便。 单独的 DFS共享文件夹的作用是相对于通过网络上的其他共享文件夹的访问点。
分布式文件系统中的数据存储在多台机器上这些专门用来存储数据的机器称之为存储节点由多个节点构成分布式集群节点上的小的分布式文件系统组合成总的分布式文件系统由主服务器对总的文件系统进行管理。用户任意访问某一台主机都能获取到自己想要的目标文件。
1.3.分布式文件系统的出现
分布式文件系统是面对互联网的需求而产生互联网时代对海量数据如何存储靠简单的增加硬盘的个数已经满足不了我们的要求因为硬盘传输速度有限但是数据在急剧增长另外我们还要做好数据备份、数据安全等。
采用分布式文件系统可以将多个地点的文件系统通过网络连接起来组成一个文件系统网络结点之间通过网络进行通信一台文件系统的存储和传输能力有限我们让文件在多台计算机上存储通过多台计算共同传输。
1.3.主流的分布式文件系统
NFS网络文件系统GFSgoogleFSHDFShadoop分布式文件系统FastDFS
1.4.分布式文件服务提供商
1.4.1.阿里OSS
对象存储服务Object Storage ServiceOSS是一种海量、安全、低成本、高可靠的云存储服务适合存放任意类型的文件。容量和处理能力弹性扩展多种存储类型供选择全面优化存储成本。
1.4.2.七牛云存储
1.4.3.百度云存储
二、fastDFS
2.1.fastDSF介绍
FastDFS是用c语言编写的一款开源的分布式文件系统它是由淘宝资深架构师余庆编写并开源。 FastDFS专为互联网量身定制充分考虑了冗余备份、负载均衡、线性扩容等机制并注重高可用、高性能等指标使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
FastDFS 系统有三个角色跟踪服务器(Tracker Server)、存储服务器(Storage Server)和客户端(Client)。
Tracker Server跟踪服务器主要做调度工作起到均衡的作用负责管理所有的 storage server和 group每个 storage 在启动后会连接 Tracker告知自己所属 group 等信息并保持周期性心跳。Storage Server存储服务器主要提供容量和备份服务以 group 为单位每个 group 内可以有多台 storage server数据互为备份。Client客户端上传下载数据的服务器也就是我们自己的项目所部署在的服务器。
2.2.为什么要使用fastDFS
NFS、GFS都是通用的分布式文件系统通用的分布式文件系统的优点的是开发体验好但是系统复杂性高、性能一般而专用的分布式文件系统虽然开发体验性差但是系统复杂性低并且性能高。 fastDFS非常适合存储图片等那些小文件fastDFS不对文件进行分块所以它就没有分块合并的开销fastDFS网络通信采用socket通信速度很快。
FastDFS特点
分组存储简单灵活对等结构不存在单点文件ID由FastDFS生成作为文件访问凭证。FastDFS不需要传统的name server或meta server大、中、小文件均可以很好支持可以存储海量小文件一台storage支持多块磁盘支持单盘数据恢复提供了nginx扩展模块可以和nginx无缝衔接支持多线程方式上传和下载文件支持断点续传存储服务器上可以保存文件附加属性。
2.3.fastDSF工作原理
2.3.1.fastDSF架构
FastDFS架构包括 Tracker server和Storageserver。
客户端请求Tracker server进行文件上传、下载通过Tracker server调度最终由Storage server完成文件上传和下载。 1Tracker
Tracker Server作用是负载均衡和调度通过Tracker server在文件上传时可以根据一些策略找到Storage server提供文件上传服务。 可以将tracker称为追踪服务器或调度服务器。
FastDFS集群中的Tracker server可以有多台Tracker server之间是相互平等关系同时提供服务Tracker server不存在单点故障。 客户端请求Tracker server采用轮询方式如果请求的tracker无法提供服务则换另一个tracker。
2Storage Storage Server作用是文件存储客户端上传的文件最终存储在Storage服务器上Storage server没有实现自己的文件系统而是使用操作系统的文件系统来管理文件。可以将storage称为存储服务器。
Storage集群采用了分组存储方式。storage集群由一个或多个组构成集群存储总容量为集群中所有组的存储容量之和。一个组由一台或多台存储服务器组成组内的Storage server之间是平等关系不同组的Storage server之间不会相互通信同组内的Storage server之间会相互连接进行文件同步从而保证同组内每个storage上的文件完全一致的。一个组的存储容量为该组内存储服务器容量最小的那个由此可见组内存储服务器的软硬件配置最好是一致的。
采用分组存储方式的好处是灵活、可控性较强。比如上传文件时可以由客户端直接指定上传到的组也可以由tracker进行调度选择。一个分组的存储服务器访问压力较大时可以在该组增加存储服务器来扩充服务能力纵向扩容。当系统容量不足时可以增加组来扩充存储容量横向扩容。
3Storage状态收集
Storage server会连接集群中所有的Tracker server定时向他们报告自己的状态包括磁盘剩余空间、文件同步状况、文件上传下载次数等统计信息。
2.3.2.文件上传流程 storage定时向tracker上传状态信息Client向tracker上传连接请求tracker查询可用的storagetracker向client返回信息storage的ip和端口client向storage上传文件file content和metadatastorage生成一个file_idstorage将上传内容写入磁盘storage向client返回file_id文件名和文件存储的路径信息client完成文件信息的存储
客户端上传文件后存储服务器将文件ID返回给客户端此文件ID用于以后访问该文件的索引信息。 文件索引信息包括组名虚拟磁盘路径数据两级目录文件名。 group1 /M00 /02/44/ wKgDrE34E8wAAAAAAAAGkEIYJK42378.sh 组名文件上传后所在的storage组名称在文件上传成功后有storage服务器返回需要客户端自行保存。虚拟磁盘路径storage配置的虚拟路径与磁盘选项store_path*对应。如果配置了store_path0则是M00如果配置了store_path1则是M01以此类推。数据两级目录storage服务器在每个虚拟磁盘路径下创建的两级目录用于存储数据文件。文件名与文件上传时不同。是由存储服务器根据特定信息生成文件名包含源存储服务器IP地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息。
2.3.3.文件下载流程 storage定时向tracker上传状态信息client向tracker提交下载连接请求tracker查询可用的storagetracker向client返回信息storage的ip和端口client向storage提交信息file_id组名、路径、文件名storage查看文件storage返回file_content给client
tracker根据请求的文件路径即文件ID 来快速定义文件。比如请求下边的文件 通过组名tracker能够很快的定位到客户端需要访问的存储服务器组是group1并选择合适的存储服务器提供客户端访问。存储服务器根据“文件存储虚拟磁盘路径”和“数据文件两级目录”可以很快定位到文件所在目录并根据文件名找到客户端需要访问的文件。
三、fastDFS入门
3.1.fastDFS安装与配置
详见https://blog.csdn.net/qq_45740503/article/details/136086731
3.2.文件上传下载测试
3.2.1.搭建环境
参考官方文档java版本的fastdfs-client地址在https://github.com/happyfish100/fastdfs-client-java参考此工程编写测试用例。
3.2.1.1.创建maven工程
3.2.1.2.添加依赖
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion3.2.0/version/parentgroupIdcom.orange/groupIdartifactIdfastDFSLearn01/artifactIdversion1.0-SNAPSHOT/versiondependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!--fastdfs-client-java依赖需要自己手动打包上传到本地仓库--dependencygroupIdorg.csource/groupIdartifactIdfastdfs-client-java/artifactIdversion1.31-SNAPSHOT/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-io/artifactIdversion1.3.2/version/dependency/dependencies/project3.2.1.3.配置文件 在classpath:config下创建fastdfs-client.properties文件 ## fastdfs-client.properties#fastDFS连接超时时间针对socket套接字函数connect
connect_timeout_in_seconds 5
#fastDFS网络超时时间
network_timeout_in_seconds 30#编码格式
charset UTF-8#是否启用token验证(针对fdfs配置文件/etc/fdfs/http.conf防盗链)
http_anti_steal_token false
#连接密钥(http.conf要配置一样的密钥)
http_secret_key FastDFS1234567890
#tracker服务器访问端口
http_tracker_http_port 80#tracker服务器地址多个以逗号隔开
fastdfs.tracker_servers 192.168.229.141:221223.2.2.文件上传
3.2.2.1.文件上传代码实现
/*** 在此文件中通过fastDSF的client代码访问tracker和storage* 通过client的api代码方便 访问 tracker和storage,它们中间走的socket协议*/
public class TestFastDFSUpload {//测试文件上传Testpublic void Upload() {//通过fastDSF的client代码访问tracker和storagetry {//加载fastDFS客户端的配置 文件ClientGlobal.initByProperties(config/fastdfs-client.properties);System.out.println(network_timeout ClientGlobal.g_network_timeout ms);System.out.println(charset ClientGlobal.g_charset);//创建tracker的客户端TrackerClient trackerClient new TrackerClient(ClientGlobal.getG_tracker_group());//通过TrackerClient对象获取TrackerServer信息//1.29版本以前的方法//TrackerServer trackerServer trackerClient.getConnection();//没有trackerClient.getConnection()方法的问题解决//1.29版本以后的fastdfs的方法更新TrackerServer trackerServer trackerClient.getTrackerServer();StorageServer storageServer null;//每次调用的时候会重新new一个StorageClient()实例这样每次请求拿到的就是不同的StorageClient//也就意味着每个请求会获取到不同的storageServer这样就不存在共享变量也就避免了出现并发的空指针问题//最好的解决方案就是每次调用的时候new一个新的实例去使用。在使用FastDFS的时候尽量不要重用StorageClient//参考文章https://blog.csdn.net/luckykapok918/article/details/80938257//定义storage的客户端,建立与Storage服务器的连接StorageClient1 storageClient new StorageClient1(trackerServer, storageServer);//文件元信息NameValuePair[] metaList new NameValuePair[1];metaList[0] new NameValuePair(fileName, 52.png);String path D:\\image\\52.png;//执行上传String fileInfoes storageClient.upload_file1(path, png, metaList);System.out.println(upload success. file id is: fileInfoes);//关闭storage客户端storageClient.close();} catch (Exception ex) {ex.printStackTrace();}}
}3.2.2.2.运行结果
network_timeout30000ms
charsetUTF-8
upload success. file id is: group1/M00/00/00/wKjljWXHAauARHa2AAWwwNOt0hY257.pngProcess finished with exit code 03.2.2.3.测试上传结果-访问
cd /home/fastdfs/fdfs_storage/data/00/00http://192.168.229.141/group1/M00/00/00/wKjljWXHAauARHa2AAWwwNOt0hY257.png3.2.3.文件查询
3.2.3.1.文件查询代码实现
public class TestFastDFSQuery {//测试文件查询Testpublic void Query() {//通过fastDSF的client代码访问tracker和storagetry {//加载fastDFS客户端的配置 文件ClientGlobal.initByProperties(config/fastdfs-client.properties);System.out.println(network_timeout ClientGlobal.g_network_timeout ms);System.out.println(charset ClientGlobal.g_charset);//创建tracker的客户端TrackerClient trackerClient new TrackerClient(ClientGlobal.getG_tracker_group());//通过TrackerClient对象获取TrackerServer信息TrackerServer trackerServer trackerClient.getTrackerServer();StorageServer storageServer null;//定义storage的客户端,建立与Storage服务器的连接StorageClient1 storageClient new StorageClient1(trackerServer, storageServer);//查询文件//upload success. file id is: group1/M00/00/00/wKjljWXHAauARHa2AAWwwNOt0hY257.pngString group_name group1;String remoteFileName M00/00/00/wKjljWXHAauARHa2AAWwwNOt0hY257.png;String file_id group1/M00/00/00/wKjljWXHAauARHa2AAWwwNOt0hY257.png;FileInfo fileInfo storageClient.query_file_info(group_name, remoteFileName);System.out.println(fileInfo);FileInfo fileInfo1 storageClient.query_file_info1(file_id);System.out.println(fileInfo1);//查询文件元信息NameValuePair[] metadata storageClient.get_metadata1(file_id);for (NameValuePair pair : metadata) {System.out.println(文件元信息 : pair.getName() , pair.getValue());}//关闭storage客户端storageClient.close();} catch (Exception ex) {ex.printStackTrace();}}
}3.2.3.2.运行结果
network_timeout30000ms
charsetUTF-8
fetch_from_server true, file_type 1, source_ip_addr 192.168.229.141, file_size 372928, create_timestamp 2024-02-10 12:55:07, crc32 -743583210
fetch_from_server true, file_type 1, source_ip_addr 192.168.229.141, file_size 372928, create_timestamp 2024-02-10 12:55:07, crc32 -743583210
文件元信息 : fileName ,52.pngProcess finished with exit code 03.2.4.文件下载
3.2.4.1.文件下载代码实现
public class TestFastDFSDownload {//测试文件下载Testpublic void Download() {//通过fastDSF的client代码访问tracker和storagetry {//加载fastDFS客户端的配置 文件ClientGlobal.initByProperties(config/fastdfs-client.properties);System.out.println(network_timeout ClientGlobal.g_network_timeout ms);System.out.println(charset ClientGlobal.g_charset);//创建tracker的客户端TrackerClient trackerClient new TrackerClient(ClientGlobal.getG_tracker_group());//通过TrackerClient对象获取TrackerServer信息TrackerServer trackerServer trackerClient.getTrackerServer();StorageServer storageServer null;//定义storage的客户端,建立与Storage服务器的连接StorageClient1 storageClient new StorageClient1(trackerServer, storageServer);//查询文件//upload success. file id is: group1/M00/00/00/wKjljWXHAauARHa2AAWwwNOt0hY257.pngString group_name group1;String remoteFileName M00/00/00/wKjljWXHAauARHa2AAWwwNOt0hY257.png;String file_id group1/M00/00/00/wKjljWXHAauARHa2AAWwwNOt0hY257.png;FileInfo fileInfo storageClient.query_file_info(group_name, remoteFileName);System.out.println(fileInfo fileInfo);if (fileInfo null) {System.out.println(您下载的文件信息不存在请核对后再次下载......);return;}byte[] bytes storageClient.download_file1(file_id);File file new File(D:\\image\\a.png);FileOutputStream fos new FileOutputStream(file);fos.write(bytes);fos.close();//关闭storage客户端storageClient.close();} catch (Exception ex) {ex.printStackTrace();}}
}3.2.4.2.运行结果
network_timeout30000ms
charsetUTF-8
fileInfo fetch_from_server true, file_type 1, source_ip_addr 192.168.229.141, file_size 372928, create_timestamp 2024-02-10 12:55:07, crc32 -743583210Process finished with exit code 03.2.5.文件删除
3.2.5.1.文件删除代码实现
public class TestFastDFSDelete {//测试文件删除Testpublic void Delete() {try {//加载fastDFS客户端的配置 文件ClientGlobal.initByProperties(config/fastdfs-client.properties);System.out.println(network_timeout ClientGlobal.g_network_timeout ms);System.out.println(charset ClientGlobal.g_charset);//创建tracker的客户端TrackerClient trackerClient new TrackerClient(ClientGlobal.getG_tracker_group());//通过TrackerClient对象获取TrackerServer信息TrackerServer trackerServer trackerClient.getTrackerServer();StorageServer storageServer null;//定义storage的客户端,建立与Storage服务器的连接StorageClient1 storageClient new StorageClient1(trackerServer, storageServer);//查询文件//upload success. file id is: group1/M00/00/00/wKjljWXHAauARHa2AAWwwNOt0hY257.pngString group_name group1;String remoteFileName M00/00/00/wKjljWXHAauARHa2AAWwwNOt0hY257.png;String file_id group1/M00/00/00/wKjljWXHAauARHa2AAWwwNOt0hY257.png;FileInfo fileInfo storageClient.query_file_info(group_name, remoteFileName);System.out.println(fileInfo fileInfo);if (fileInfo null) {System.out.println(您删除的文件信息不存在请核对后再次删除......);return;}storageClient.delete_file1(file_id);System.out.println(删除成功);//关闭storage客户端storageClient.close();} catch (Exception ex) {ex.printStackTrace();}}
}3.2.5.2.运行结果
network_timeout30000ms
charsetUTF-8
fileInfo fetch_from_server true, file_type 1, source_ip_addr 192.168.229.141, file_size 372928, create_timestamp 2024-02-10 12:55:07, crc32 -743583210
删除成功Process finished with exit code 03.2.5.3.服务器查看 3.3.recv body length: 70 is not correct, expect length: 40
network_timeout30000ms
charsetUTF-8
java.io.IOException: recv body length: 70 is not correct, expect length: 40at org.csource.fastdfs.ProtoCommon.recvHeader(ProtoCommon.java:186)at org.csource.fastdfs.ProtoCommon.recvPackage(ProtoCommon.java:201)at org.csource.fastdfs.TrackerClient.getStoreStorage(TrackerClient.java:130)at org.csource.fastdfs.StorageClient.newWritableStorageConnection(StorageClient.java:1627)at org.csource.fastdfs.StorageClient.do_upload_file(StorageClient.java:639)at org.csource.fastdfs.StorageClient.upload_file(StorageClient.java:120)at org.csource.fastdfs.StorageClient.upload_file(StorageClient.java:91)at org.csource.fastdfs.StorageClient.upload_file(StorageClient.java:73)at org.csource.fastdfs.StorageClient1.upload_file1(StorageClient1.java:64)server 端使用 V6.11fastdfs-clint-java需要使用最新的 V1.31
3.3.1.解决问题修改依赖
dependencygroupIdorg.csource/groupIdartifactIdfastdfs-client-java/artifactIdversion1.31-SNAPSHOT/version
/dependency3.3.2.下载源码打包成jar包并上传到本地maven仓库
FastDFS java下载官网https://github.com/happyfish100/fastdfs-client-java
源码及本人打包好的jar包https://www.lanzv.com/b05ew922f 密码:deca
3.3.2.1.下载解压 3.3.2.2.使用maven从源码安装
mvn -versionmvn clean install3.3.2.3.进入/target 目录执行CMD 命令将jar包打包到本地maven仓库
mvn install:install-file -DgroupIdorg.csource -DartifactIdfastdfs-client-java -Dversion${version} -Dpackagingjar -Dfilefastdfs-client-java-${version}.jar执行以下命令【具体版本路径按实际修改】
mvn install:install-file -DgroupIdorg.csource -DartifactIdfastdfs-client-java -Dversion1.31-SNAPSHOT -Dpackagingjar -DfileD:\FastDFS-java\fastdfs-client-java-1.31\target\fastdfs-client-java-1.31-SNAPSHOT.jar3.3.2.4.在maven项目pom.xml中添加fastdfs-client-java依赖
dependencygroupIdorg.csource/groupIdartifactIdfastdfs-client-java/artifactIdversion1.31-SNAPSHOT/version
/dependency四、文件服务案例
4.1.目标使用fastDSF实现图片服务器
4.2.需求分析 4.3.功能开发
4.3.1.搭建fastDFS文件服务器 4.3.2.搭建文件管理服务
4.3.2.1.添加依赖
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion3.2.0/version/parentgroupIdcom.orange/groupIdartifactIdfastDFSLearn01/artifactIdversion1.0-SNAPSHOT/versiondependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!--fastdfs-client-java依赖需要自己手动打包上传到本地仓库--dependencygroupIdorg.csource/groupIdartifactIdfastdfs-client-java/artifactIdversion1.31-SNAPSHOT/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-io/artifactIdversion1.3.2/version/dependency/dependencies/project4.3.2.2.fastdfs-client配置文件
fastdfs-client.properties
## fastdfs-client.properties#fastDFS连接超时时间针对socket套接字函数connect
connect_timeout_in_seconds 5
#fastDFS网络超时时间
network_timeout_in_seconds 30#编码格式
charset UTF-8#是否启用token验证(针对fdfs配置文件/etc/fdfs/http.conf防盗链)
http_anti_steal_token false
#连接密钥(http.conf要配置一样的密钥)
http_secret_key FastDFS1234567890
#tracker服务器访问端口
http_tracker_http_port 80#tracker服务器地址多个以逗号隔开
fastdfs.tracker_servers 192.168.229.141:221224.3.2.3.跨域配置CrossConfig.java
Configuration
public class CrossConfig implements WebMvcConfigurer {Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping(/**)// 对所有路径应用跨域配置,所有的当前站点的请求地址都支持跨域访问。//是否发送Cookie.allowCredentials(true)//放行哪些原始域.allowedHeaders(*).allowedMethods(POST, GET, HEAD, PUT, OPTIONS, DELETE).allowedOriginPatterns(*)// 所有的外部域都可跨域访问。// 如果是localhost则很难配置因为在跨域请求的时候外部域的解析可能是localhost、127.0.0.1、主机名.maxAge(3600);// 超时时长设置为1小时。 时间单位是秒。}
}4.3.2.4.创建模型–实体类
4.3.2.4.1.FileSystem.java
Data
NoArgsConstructor
AllArgsConstructor
public class FileSystem {private String fileId;private String filePath;private Long fileSize;private String fileName;private String fileType;
}4.3.2.4.2.Result.java
Data
NoArgsConstructor
AllArgsConstructor
public class Result {private Integer code;//响应码1 代表成功; 0 代表失败private String msg; //响应信息 描述字符串private Object data; //返回的数据//增删改 成功响应public static Result success(){return new Result(1,success,null);}//查询 成功响应public static Result success(Object data){return new Result(1,success,data);}//失败响应public static Result error(String msg){return new Result(0,msg,null);}
}4.3.2.5.创建controller
Slf4j
RestController
RequestMapping(/filesystem)
public class FileServerController {Value(${orange-fastdfs.upload_location})private String upload_location;PostMapping(/uploadFile)ResponseBodypublic Result upload(RequestParam(file) MultipartFile file) throws IOException {//将文件先存储在web服务器上(本机),在调用fastDFS的client将文件上传到 fastDFS服务器FileSystem fileSystem new FileSystem();//文件原始名称String originalFilename file.getOriginalFilename();//文件扩展名比如22.jpgString extension originalFilename.substring(originalFilename.lastIndexOf(.));log.info(文件扩展名后缀 {}, extension);//.jpgString filenameExtension StringUtils.getFilenameExtension(originalFilename);log.info(文件类型 {}, filenameExtension);//jpgif (filenameExtension null) {return Result.error(此文件没有文件扩展名);}//新文件名称String fileName UUID.randomUUID().toString().replace(-, ) . filenameExtension;log.info(新文件名称 {}, fileName);//定义file,使用file存储上传的文件//File file1 new File(D:\\image\\upload\\ fileName);File file1 new File(upload_location fileName);//指定照片上传路径,上传的文件写入到新的文件file.transferTo(file1);//获取新上传文件的物理路径String newFilePath file1.getAbsolutePath();//通过fastDSF的client代码访问tracker和storagetry {//加载fastDFS客户端的配置 文件ClientGlobal.initByProperties(config/fastdfs-client.properties);System.out.println(network_timeout ClientGlobal.g_network_timeout ms);System.out.println(charset ClientGlobal.g_charset);//创建tracker的客户端TrackerClient trackerClient new TrackerClient(ClientGlobal.getG_tracker_group());//通过TrackerClient对象获取TrackerServer信息TrackerServer trackerServer trackerClient.getTrackerServer();StorageServer storageServer null;//定义storage的客户端,建立与Storage服务器的连接StorageClient1 storageClient new StorageClient1(trackerServer, storageServer);//文件元信息NameValuePair[] metaList new NameValuePair[1];metaList[0] new NameValuePair(fileName, 52.png);//执行上传String fileId storageClient.upload_file1(newFilePath, filenameExtension, metaList);System.out.println(upload success. file id is: fileId);fileSystem.setFileId(fileId);fileSystem.setFilePath(fileId);fileSystem.setFileName(originalFilename);fileSystem.setFileSize(file.getSize());fileSystem.setFileType(filenameExtension);//通过调用service及dao将文件的路径存储到数据库中//关闭storage客户端storageClient.close();} catch (Exception ex) {ex.printStackTrace();}return Result.success(fileSystem);}
}4.3.2.6.创建优化后的controller代码
Slf4j
RestController
RequestMapping(/filesystem)
public class FileServerController {PostMapping(/uploadFile)ResponseBodypublic Result upload(RequestParam(file) MultipartFile file) throws IOException {//将文件先存储在web服务器上(本机),在调用fastDFS的client将文件上传到 fastDFS服务器FileSystem fileSystem new FileSystem();String contentType file.getContentType();log.info(上传的文件类型为{}, contentType);byte[] file_buff null;//把文件转成输入流InputStream inputStream file.getInputStream();if (inputStream ! null) {//获取输入流中可读取的数据大小int len inputStream.available();//创建足够大的缓冲区file_buff new byte[len];//一次性把输入流中的数据全都读入到缓冲区file_buff,那file_buff就要足够大,占用内存也会很大inputStream.read(file_buff);}//关闭输入流inputStream.close();//文件原始名称String originalFilename file.getOriginalFilename();//文件扩展名比如22.jpgString extension originalFilename.substring(originalFilename.lastIndexOf(.));log.info(文件扩展名后缀 {}, extension);//.jpgString filenameExtension StringUtils.getFilenameExtension(originalFilename);log.info(文件类型 {}, filenameExtension);//jpgif (filenameExtension null) {return Result.error(此文件没有文件扩展名);}//通过fastDSF的client代码访问tracker和storagetry {//加载fastDFS客户端的配置 文件ClientGlobal.initByProperties(config/fastdfs-client.properties);System.out.println(network_timeout ClientGlobal.g_network_timeout ms);System.out.println(charset ClientGlobal.g_charset);//创建tracker的客户端TrackerClient trackerClient new TrackerClient(ClientGlobal.getG_tracker_group());//通过TrackerClient对象获取TrackerServer信息TrackerServer trackerServer trackerClient.getTrackerServer();StorageServer storageServer null;//定义storage的客户端,建立与Storage服务器的连接StorageClient1 storageClient new StorageClient1(trackerServer, storageServer);//文件元信息NameValuePair[] metaList new NameValuePair[1];metaList[0] new NameValuePair(fileName, 52.png);//执行上传String fileId storageClient.upload_file1(file_buff, filenameExtension, metaList);System.out.println(upload success. file id is: fileId);fileSystem.setFileId(fileId);fileSystem.setFilePath(fileId);fileSystem.setFileName(originalFilename);fileSystem.setFileSize(file.getSize());fileSystem.setFileType(contentType);//通过调用service及dao将文件的路径存储到数据库中//关闭storage客户端storageClient.close();} catch (Exception e) {log.error(上传文件失败, e);e.printStackTrace();}return Result.success(fileSystem);}
}4.3.2.7.创建application.yml
server:port: 22100orange-fastdfs:#文件上传临时目录upload_location: D:\\image\\upload\\# linux临时文件目录
# mkdir -p /data/tmp/updatefile
spring:servlet:multipart:location: /data/tmp/updatefile4.3.2.8.创建spring boot启动类
SpringBootApplication
public class FileServerApplication {public static void main(String[] args) {SpringApplication.run(FileServerApplication.class, args);}
}4.3.3.管理系统前端【Vue2】项目
4.3.3.1.axios模块
4.3.3.1.1.安装axios模块
vue-axios|axios中文网http://www.axios-js.com/zh-cn/docs/vue-axios.html axios官网https://www.axios-http.cn/docs/intro
npm install --save axios vue-axios//报错时使用--legacy-peer-deps
npm install --save axios vue-axios --legacy-peer-deps4.3.3.1.2.在入口文件main.js中配置axios
#在入口文件main.js中配置
//引入vue
import Vue from vue
//引入axios
import axios from axios
//引入VueAxios
//安装VueAxios模块后不需要在每个组件中单独导入axios只需将axios请求改为this.axios
import VueAxios from vue-axios
//把axios挂载到vue上
Vue.prototype.$axios axios;//使用Vue.use来注册安装插件
Vue.use(VueAxios, axios)new Vue({el:#app,render: h h(App),
})按照这个顺序分别引入这三个文件 vue, axios and vue-axios4.3.3.1.3.axios使用案例
# 在入口文件main.js中配置
//引入Vue
import Vue from vue
//引入axios
import axios from axios
//把axios挂载到vue上
Vue.prototype.$axios axiosnew Vue({el:#app,render: h h(App),
})# 第三步使用案例
this.$axios.get(/user?id888).then((response) {console.log(response.data)
}).catch( (error) {console.log(error);
});4.3.3.1.4.vue-axios使用案例
#在入口文件main.js中配置
//引入Vue
import Vue from vue
//引入axios
import axios from axios
//引入VueAxios
import VueAxios from vue-axios//使用Vue.use来注册安装插件
Vue.use(VueAxios, axios)new Vue({el:#app,render: h h(App),
})#第三步使用方式有如下三种
#方式1
Vue.axios.get(api).then((response) {console.log(response.data)
})
#方式2
this.axios.get(api).then((response) {console.log(response.data)
})
#方式3
this.$http.get(api).then((response) {console.log(response.data)
})4.3.3.2.关闭Vue的生产提示
#在入口文件main.js中配置
//关闭Vue的生产提示
Vue.config.productionTip false4.3.3.3.vue项目中无router文件夹vue安装路由 新建一个router文件夹在文件夹下新建一个index.js文件 4.3.3.4.引入Vue Router路由Vue.js【v.3x】
Vue2使用v.3x Vue Router官网【v3.x】https://v3.router.vuejs.org/zh/ 更新记录【3.x】https://github.com/vuejs/vue-router/releases
//报错时使用--legacy-peer-deps
//vue-router3x 适用于 vue2
npm install vue-router3//指定版本号
npm install vue-router3.5.2 --save#在入口文件main.js中配置
//引入VueRouter
import VueRouter from vue-router//使用Vue.use来注册安装插件
Vue.use(VueRouter)//新建一个router文件夹在文件夹下新建一个index.js文件
//引入路由器
import router from ./router/index// 创建和挂载根实例
new Vue({router, //将路由器注入到new Vue实例中建立关联render: h h(App),
}).$mount(#app);4.3.3.5.引入ElementUI组件库【Vue2 版本】
ElementUI组件库官网https://element.eleme.cn/#/zh-CN
npm i element-ui -S//完整引入
//引入ElementUI组件库
import ElementUI from element-ui
import element-ui/lib/theme-chalk/index.css//使用ElementUI组件库
Vue.use(ElementUI)4.3.3.6.main.js完整版 import App from ./App.vue
//引入Vue
import Vue from vue
//引入axios
import axios from axios
//引入VueAxios
//安装VueAxios模块后不需要在每个组件中单独导入axios只需将axios请求改为this.axios
import VueAxios from vue-axios
//引入VueRouter
import VueRouter from vue-router
//完整引入
//引入ElementUI组件库
import ElementUI from element-ui
import element-ui/lib/theme-chalk/index.css
//新建一个router文件夹在文件夹下新建一个index.js文件
//引入路由器
import router from ./router/index//把axios挂载到vue上
Vue.prototype.$axios axios;
//使用Vue.use来注册安装插件
Vue.use(VueRouter)
Vue.use(router)
Vue.use(VueAxios, axios)
//使用ElementUI组件库
Vue.use(ElementUI)
//关闭Vue的生产提示
Vue.config.productionTip false// 创建和挂载根实例
new Vue({router, //将路由器注入到new Vue实例中建立关联render: h h(App),
}).$mount(#app);4.3.3.7.页面创建UploadImg.vue
templatedivel-formel-form-item label上传图片el-uploadlist-typepicture-card:multiplefalse:actionuploadUrl:limit1:on-successonUploadSuccessIdCardi classel-icon-plus/i/el-upload/el-form-item/el-form/div
/templatescript
export default {name: UploadImg,data() {return {dialogImageUrl: ,file_id: ,dialogVisible: false,uploadUrl: http://localhost:22100/filesystem/uploadFile, //文件上传地址datas: {},};},methods: {onUploadSuccessIdCard(response) {this.file_id response.data.fileId;this.datas response.data;this.dialogImageUrl http://192.168.229.141/ response.data.filePath;},},
};
/scriptstyle scoped
/style4.3.3.8.修改App.vue
templatediv idappHelloWorld /!-- 导航链接 --!-- 路由内容展示 --router-view/router-view/div
/templatescript
export default {name: App,
};
/scriptstyle
/style4.3.3.9.创建路由配置router/index.js
//在路由文件router/index.js中配置
// 该文件专门用于创建整个应用的路由器
import VueRouter from vue-router;//引入组件
import UploadImg from /components/UploadImg//上传页//创建路由
const routes [//定义路由{path: /,name: UploadImg,component: UploadImg},
]//创建并暴露一个路由器
const router new VueRouter({mode: history,base: process.env.BASE_URL,routes
})export default router4.3.3.10.课程图片浏览
npm rn serve4.3.4.管理系统前端【Vue3】项目
4.3.4.1.axios模块
4.3.4.1.1.安装axios模块
vue-axios|axios中文网http://www.axios-js.com/zh-cn/docs/vue-axios.html axios官网https://www.axios-http.cn/docs/intro
npm install --save axios vue-axios//报错时使用--legacy-peer-deps
npm install --save axios vue-axios --legacy-peer-deps4.3.4.1.2.在入口文件main.js中配置axios
#在入口文件main.js中配置
import { createApp } from vue
import App from ./App.vue//引入axios
import axios from axios
//引入VueAxios
//安装VueAxios模块后不需要在每个组件中单独导入axios只需将axios请求改为this.axios
import VueAxios from vue-axiosconst app createApp(App);//使用Vue.use来注册安装插件
app.use(VueAxios, axios)app.mount(#app)//createApp(App).mount(#app)按照这个顺序分别引入这三个文件 vue, axios and vue-axios4.3.4.2.关闭Vue的生产提示
#在入口文件main.js中配置
//关闭Vue的生产提示
app.config.productionTip false4.3.4.3.vue项目中无router文件夹vue安装路由 新建一个router文件夹在文件夹下新建一个index.js文件 4.3.4.4.引入Vue Router路由Vue.js【v.4x】
Vue3使用v.4x Vue Router官网【v4.x】https://router.vuejs.org/zh/ 更新记录【4.x】https://github.com/vuejs/router/releases
//vue-router4x 适用于 vue3
npm install vue-router4//指定版本号
npm install vue-router4.2.5 --saveimport { createApp } from vue
import App from ./App.vue//引入路由器
import router from ./router/indexconst app createApp(App);//使用Vue.use来注册安装插件
app.use(router)app.mount(#app)4.3.4.5.引入Element Plus组件库【Vue3 版本】
Element Plus组件库官网https://element-plus.gitee.io/zh-CN/
npm install element-plus --save// main.ts
import { createApp } from vue
//引入Element Plus组件库
import ElementPlus from element-plus
import element-plus/dist/index.css
import App from ./App.vueconst app createApp(App)app.use(ElementPlus)
app.mount(#app)4.3.4.6.main.js完整版
import { createApp } from vue
import App from ./App.vue//引入axios
import axios from axios
//引入VueAxios
//安装VueAxios模块后不需要在每个组件中单独导入axios只需将axios请求改为this.axios
import VueAxios from vue-axios
//新建一个router文件夹在文件夹下新建一个index.js文件
//引入路由器
import router from ./router/index
//引入Element Plus组件库
import ElementPlus from element-plus
import element-plus/dist/index.cssconst app createApp(App);
//关闭Vue的生产提示
app.config.productionTip false//使用Vue.use来注册安装插件
app.use(VueAxios, axios)
app.use(router)
app.use(ElementPlus)app.mount(#app)4.3.4.7.页面创建UploadImg.vue
templatedivel-formel-form-item label上传图片el-uploadlist-typepicture-card:multiplefalse:actionuploadUrl:limit1:on-successonUploadSuccessIdCardi classel-icon-plus/i/el-upload/el-form-item/el-form/div
/templatescript
export default {name: UploadImg,data() {return {dialogImageUrl: ,file_id: ,dialogVisible: false,uploadUrl: http://localhost:22100/filesystem/uploadFile, //文件上传地址datas: {},};},methods: {onUploadSuccessIdCard(response) {this.file_id response.data.fileId;this.datas response.data;this.dialogImageUrl http://192.168.229.141/ response.data.filePath;},},
};
/scriptstyle scoped
/style4.3.4.8.修改App.vue
templatediv idappHelloWorld /!-- 导航链接 --!-- 路由内容展示 --router-view/router-view/div
/templatescript
export default {name: App,
};
/scriptstyle
/style4.3.4.9.创建路由配置router/index.js
import { createRouter, createWebHistory } from vue-routerconst routerHistory createWebHistory(process.env.BASE_URL)import UploadImg from /components/UploadImg
// 定义路由
const routes [{path: /,name: UploadImg,component: UploadImg},
]// 创建路由器
const router createRouter({history: routerHistory,routes: routes
})export default router;4.3.4.10.页面效果
npm rn serve五、总结
分布式文件系统是通过网络将单机上的文件系统组成一个网络文件系统分布式文件系统主要应用在大型互联网项目中实现图片存储、音视频存储等服务分布式文件系统的优点可以快速扩容存储提高文件访问速度fastDFS的工作原理fastDFS由tracker和storage组成它们都可以部署集群。tracker负责调度storage负责存储fastDFS存取文件方法客户端与fastDFS采用socket协议通信采用官方提供的java版本的fastDSF-client快速开发能够动手搭建一个fastDSF文件服务器
endl