• 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;
  • 相关阅读:
    主机不能访问虚拟机CentOS中的站点
    linux安装redis
    java获去json所有对象
    Java nio和io
    [shell基础]——if/for/while/until/case 语句
    [shell基础]——整数比较;字符串比较;文件测试;逻辑测试符
    [shell基础]——数组
    [shell基础]——I/O重定向
    [shell基础]——tr命令
    [shell基础]——split命令
  • 原文地址:https://www.cnblogs.com/HQ0422/p/12564323.html
Copyright © 2020-2023  润新知