FastDFS
Posted hq0422
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FastDFS相关的知识,希望对你有一定的参考价值。
FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储,文件同步,文件访问(文件上传下载)等,他解决了大容量存储和负载均衡的问题,特别适合以文件为载体的在线服务,如相册网站,视频网站等
FastDFS充分考虑了冗余备份,负载均衡,线性扩容等机制,并注重高可用,高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传,下载等服务
FastDFS架构包括Tracker server 和Storage server 客户端请求Tracker server 进行文件上传,下载,通过Tracker server调度最终由Storage server完成文件上传和下载
2.Tracker server作用
Tracker server 的作用是负载均衡和调度,通过Tracker server 在文件上传时可以根据一些策略找到Storage server 提供上传服务,可以将tracker称为追踪服务器或调度服务器
3.Storage server作用
客户端上传的文件最终存储在Storage服务器上,Storage server没有实现自己的文件系统而是利用操作系统的文件系统来管理文件。可以将Storage server称为存储服务器
4.服务端两个角色
1.Tracker :管理集群,tracker也可以实现集群。每个tracker节点的地位平等。负责收集Storage集群的状态
2.Storage:保存文件,Storage分为多个分组,每组之间保存的文件是不同的,每个组内部可以有多个成员,成员内部保存的内容是一样的,组成员的地位是一致的,没有主从的概念
上传流程图
客户端上传文件后存储服务器将文件Id返回给客户端,此文件Id用于以后访问改文件的索引信息。文件索引信息包括:组名,虚拟磁盘路径,数据两级目录级文件名
例:
group1/M00/00/32/wKgCS114sHiAT4pGAAdRFLGbXaw.d52ca2
group1(组名):文件上传后所在的storage组名称,在文件上传成功后由storage服务器返回,需要客户端自行保存
M00(虚拟磁盘路径)
00/32(数据两级目录):storage服务在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件
wKgCS114sHiAT4pGAAdRFLGbXaw.d52ca2(文件名):与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储服务器IP地址,文件创建时间戳,文件大小,随机数据和文件拓展名等信息
例:
group1/M00/00/32/wKgCS114sHiAT4pGAAdRFLGbXaw.d52ca2
通过tracker能够很快的定位到客户端需要访问的存储服务器组是group1,并选择合适的存储服务器提供客户端访问
存储服务器根据“文件存储虚拟磁盘路径”和“数据文件两级目录”可以很快定位
例:
前台:
this.axios({ method:‘GET‘, url:"/upload/upload/downloadFile", headers:this.headers, params:{ id:id, },responseType: ‘blob‘ }).then(data=>{ if (!data) { this.$message.warning("文件下载失败") return } if (typeof window.navigator.msSaveBlob !== ‘undefined‘) { window.navigator.msSaveBlob(new Blob([data]),fileName) }else{ let url = window.URL.createObjectURL(new Blob([data])) let link = document.createElement(‘a‘) link.style.display = ‘none‘ link.href = url link.setAttribute(‘download‘,fileName) document.body.appendChild(link) link.click() document.body.removeChild(link); //下载完成移除元素 window.URL.revokeObjectURL(url); //释放掉blob对象 } })
后台:
//通过id获得图片 Upload a = getById(id); //获得文件服务器连接 FastFileStorageClient storageClient = getStorageClient(); //下载文件 byte[] bytes = storageClient.downloadFile(a.getFileGroup(), a.getFilePath()); //设置文件类型和字符编码 response.setContentType("application/octet-stream;charset=UTF-8"); //设置返回的头部信息 response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode(a.getFileName()+a.getFileType(), "UTF-8")))); response.addHeader("Content-Length", "" + bytes.length); //获得输出流 OutputStream outputStream = response.getOutputStream(); //将数组写出 outputStream.write(bytes); //冲刷缓冲区 outputStream.flush(); //关闭流 outputStream.close();
//获得文件服务器地址 public FastFileStorageClient getStorageClient() { //初始化连接池 FdfsConnectionPool pool = new FdfsConnectionPool(); // 设置tracker List<String> trackers = Arrays.asList("文件服务器ip地址:端口", "文件服务器IP地址:端口"); TrackerConnectionManager tcm = new TrackerConnectionManager(pool, trackers); TrackerClient trackerClient = new DefaultTrackerClient(tcm); // 得到storage客户端 ConnectionManager cm = new ConnectionManager(pool); FastFileStorageClient storageClient = new DefaultFastFileStorageClient(trackerClient, cm); return storageClient; }
下载图片转为base64码发送到前台
//获得文件服务链接 FastFileStorageClient sClient = getStorageClient(); //获得文件数组 byte[] bytes = sClient.downloadFile(a.getFileGroup(), a.getFilePath()); BASE64Encoder npBase64Encoder = new BASE64Encoder(); String s=npBase64Encoder.encode(bytes);
前台显示
<img width="40" height="30" src="data:image/jpeg;base64,/9j/4QMZRXhp" />
SpringBoot整合FastDFS
1.引入协议
<dependency> <groupId>com.luhuiguo</groupId> <artifactId>fastdfs-client</artifactId> <version>0.4.0</version> </dependency>
2.获得文件服务器地址
public FastFileStorageClient getStorageClient() { //初始化连接池 FdfsConnectionPool pool = new FdfsConnectionPool(); // 设置tracker List<String> trackers = Arrays.asList("192.168.2.77:55122", "192.168.2.78:55122"); TrackerConnectionManager tcm = new TrackerConnectionManager(pool, trackers); TrackerClient trackerClient = new DefaultTrackerClient(tcm); // 得到storage客户端 ConnectionManager cm = new ConnectionManager(pool); FastFileStorageClient storageClient = new DefaultFastFileStorageClient(trackerClient, cm); return storageClient; }
3.下载文件
//获得文件服务器 FastFileStorageClient sclient = getStorageClient(); //获得文件名加后缀 String fileName = file.getOriginalFilename(); //得到文件类型 String type = fileName.substring(fileName.indexOf(".")+1); //得到文件名称 String name = fileName.substring(0, fileName.indexOf(".")); //将文件发送到服务器 StorePath storePath = sclient.uploadFile(file.getBytes(), type); String group = storePath.getGroup(); String path = storePath.getPath(); //1.通过group和payh下载文件 byte[] bytes = sClient.downloadFile(group ,path ); 或 //2.通过文件路径访问 String url =文件服务器地址 + "/" + group + "/" + path;
以上是关于FastDFS的主要内容,如果未能解决你的问题,请参考以下文章
分布式文件服务器FastDFS之“文件上传后(JAVA),前(AngularJS)端代码"