• FastDFS文件上传


    分布式文件存储-FastDFS

    介绍

    FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

    FastDFS体系结构

    FastDFS 架构包括 Tracker server 和 Storage server。客户端请求 Tracker server 进行文件上传、下载,通过Tracker server 调度最终由 Storage server 完成文件上传和下载。

    架构图

    请添加图片描述

    上传流程

    请添加图片描述

    FastDFS搭建

    1.docker安装

    docker pull morunchang/fastdfs
    docker run -d --name tracker --net=host morunchang/fastdfs sh tracker.sh
    docker run -d --name storage --net=host -e TRACKER_IP=<your tracker server address>:22122 -e GROUP_NAME=<group name> morunchang/fastdfs sh storage.sh
    
    • 1
    • 2
    • 3

    2.修改nginx的配置

    docker exec -it storage  /bin/bash
    vi /data/nginx/conf/nginx.conf
    
    • 1
    • 2

    添加配置内容

    location /group1/M00 {
       proxy_next_upstream http_502 http_504 error timeout invalid_header;
         proxy_cache http-cache;
         proxy_cache_valid  200 304 12h;
         proxy_cache_key $uri$is_args$args;
         proxy_pass http://fdfs_group1;
         expires 30d;
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.重启storage服务

    docker restart storage
    
    • 1

    代码实现

    1.maven添加依赖

            
            <dependency>
                <groupId>com.github.tobatogroupId>
                <artifactId>fastdfs-clientartifactId>
                <version>1.27.2version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.配置文件

    server:
      port: 7002
    
    spring:
      application:
        name: file
    
    fdfs:
      so-timeout: 2000 # 读取时间
      connect-timeout: 1000 # 连接超时时间
      thumb-image: # 生成缩略图
        height: 150 # 缩略图高度
        width: 150 # 缩略图宽度
      tracker-list: # tracker 服务器地址
        - 192.168.200.128:22122
      web-server-url: http://192.168.200.128:8080/ # storage 服务器上nginx的地址
      pool: # 可参考 ConnectionPoolConfig
        #从池中借出的对象的最大数目(配置为-1表示不限制)
        max-total: -1
        #获取连接时的最大等待毫秒数(默认配置为5秒)
        max-wait-millis: 5000
        #每个key最大连接数  key配置的是连接服务端的地址(IP+端口)连接情况,如果有连接不够用的情况可以调整以上参数
        max-total-per-key: 50
        #每个key对应的连接池最大空闲连接数
        max-idle-per-key: 10
        #每个key对应的连接池最小空闲连接数
        min-idle-per-key: 5
        #向调用者输出“连接”资源时,是否检测有效性
        test-on-borrow: true
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    3.上传代码

    package com.tea.file.controller;
    
    import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
    import com.github.tobato.fastdfs.domain.fdfs.MetaData;
    import com.github.tobato.fastdfs.domain.fdfs.StorePath;
    import com.github.tobato.fastdfs.service.FastFileStorageClient;
    import com.tea.common.entity.ResponseResult;
    import com.tea.common.entity.StatusCode;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import lombok.AllArgsConstructor;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.io.FilenameUtils;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    
    /**
     * @className: FastDfsController
     * @author: junfeng
     * @date: 2022/11/28
     **/
    @RestController
    @AllArgsConstructor
    @RequestMapping("file")
    @Slf4j
    @Api(tags = "1 文件")
    public class FastDfsController {
    
        private final FastFileStorageClient fastFileStorageClient;
    
        private final FdfsWebServer fdfsWebServer;
    
        /**
         * 上传文件
         */
        @PostMapping("upload")
        @ApiOperation(value = "1.1 上传")
        public ResponseResult<Object> uploadFile(MultipartFile file) {
            String fileName = file.getOriginalFilename();
            // 获取文件扩展名
            String extension = FilenameUtils.getExtension(fileName);
            // 文件元数据信息
            Set<MetaData> metaData = new HashSet<>(4);
            metaData.add(new MetaData("fileName", fileName));
            // 上传文件
            StorePath storePath;
            try {
                storePath = fastFileStorageClient.uploadImageAndCrtThumbImage(file.getInputStream(), file.getSize(), extension, metaData);
            } catch (IOException e) {
                log.error(e.getMessage(), e);
                return ResponseResult.fail(StatusCode.ERROR);
            }
            log.info("文件上传路径:[{}]", storePath.getFullPath());
            String viewPath = fdfsWebServer.getWebServerUrl() + storePath.getFullPath();
            log.info("可访问路径:[{}]", viewPath);
    
            extension = FilenameUtils.getExtension(viewPath);
            String thumbPath = viewPath.replace("." + extension, "") + "_150x150." + extension;
            log.info("缩略图路径:[{}]", thumbPath);
    
            List<String> result = new ArrayList<>(3);
            result.add(viewPath);
            result.add(thumbPath);
            result.add(storePath.getFullPath());
    
            return ResponseResult.ok(result);
        }
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
      result.add(viewPath);
        result.add(thumbPath);
        result.add(storePath.getFullPath());
    
        return ResponseResult.ok(result);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    }

    
    
    • 1
  • 相关阅读:
    乐趣国学—品读《弟子规》中的“泛爱众”之道(上篇)
    基于SSM框架的图片分享及评价网站设计与实现毕业设计源码201524
    Linux 脚本 hive脚本
    【前端源码解析】AST 抽象语法树
    4+N架构:从0到1搭建保险个性化推荐能力【转载】
    Android用户切换系统语言后,回到App,App重新加载导致的一些问题[android:configChanges=“layoutDirection“]
    CDD文件——CANdelaStudio
    新版Logcat体验与分享—NEW Logcat in Android Studio Dolphin
    存储过程中双循环迭代数据
    Cron表达式详解(配合例子)
  • 原文地址:https://blog.csdn.net/qq_26347283/article/details/128114066