FastDFS

Posted hq0422

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FastDFS相关的知识,希望对你有一定的参考价值。

1.什么是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(虚拟磁盘路径):storage配置的虚拟路径,与磁盘选项store_path对应,如果配置了store_path0则是M00,如果配置了store_path1则是M01以此类推

00/32(数据两级目录):storage服务在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件

wKgCS114sHiAT4pGAAdRFLGbXaw.d52ca2(文件名):与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储服务器IP地址,文件创建时间戳,文件大小,随机数据和文件拓展名等信息

 

5.文件下载流程

技术图片

 

 

tracker根据请求的文件路径即文件ID来快速定义文件

例:

  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)端代码"

Java实现FastDFS文件上传下载和删除

Java实现FastDFS文件上传下载和删除

FastDFS - 文件服务器学习资料

关于 go-fastdfs-web 的SpringBoot 后台管理

django中使用FastDFS分布式文件系统接口代码实现文件上传下载更新删除