Spring Boot集成fastdfs快速入门Demo

1.什么是fastdfs

FastDFS 是一个开源的高性能分布式文件系统(DFS)。 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡。主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。

FastDFS 系统有三个角色:跟踪服务器(Tracker Server)、存储服务器(Storage Server)和客户端(Client)。

  • Tracker Server:跟踪服务器,主要做调度工作,起到均衡的作用;负责管理所有的 storage server和 group,每个 storage 在启动后会连接 Tracker,告知自己所属 group 等信息,并保持周期性心跳。
  • Storage Server:存储服务器,主要提供容量和备份服务;以 group 为单位,每个 group 内可以有多台 storage server,数据互为备份。
  • Client:客户端,上传下载数据的服务器,也就是我们自己的项目所部署在的服务器。

目前fastdfs基本处于淘汰阶段,大家可以尝试用minio,具体介绍 >>> Spring Boot集成Minio快速入门demo

2.fastdfs环境搭建

搜索镜像

sql 复制代码
docker search fastdfs

拉取镜像(已经内置Nginx)

bash 复制代码
docker pull delron/fastdfs

构建Tracker

bash 复制代码
# 22122 => Tracker默认端口
docker run --name=tracker-server --privileged=true -p 22122:22122 -v /var/fdfs/tracker:/var/fdfs  --network=host -d delron/fastdfs tracker

构建Storage

bash 复制代码
# 23000 => Storage默认端口
# 8888 => 内置Nginx默认端口
# TRACKER_SERVER => 执行Tracker的ip和端口
# --net=host => 避免因为Docker网络问题导致外网客户端无法上传文件,因此使用host网络模式
docker run --name=storage-server --privileged=true -p 23000:23000 -p 8888:8888 -v /var/fdfs/storage:/var/fdfs -e TRACKER_SERVER=10.11.68.77:22122 -e GROUP_NAME=group1  --network=host -d delron/fastdfs storage

查看容器

docker ps

3.代码工程

实验目的:实现文件上传

pom.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springboot-demo</artifactId>
        <groupId>com.et</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>fastdfs</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.github.tobato</groupId>
            <artifactId>fastdfs-client</artifactId>
            <version>1.26.2</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>

application.yaml

yaml 复制代码
server:
  port: 8088
fdfs:
  soTimeout: 1500
  connectTimeout: 600
  thumbImage:             #thumbImage param
    width: 150
    height: 150
  trackerList:            #TrackerList参数,支持多个
    - 10.11.68.77:22122

controller

typescript 复制代码
package com.et.fastdfs.controller;

import com.et.fastdfs.util.FastDFSClientWrapper;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
@RestController
public class HelloWorldController {
    @RequestMapping("/hello")
    public Map<String, Object> showHelloWorld(){
        Map<String, Object> map = new HashMap<>();
        map.put("msg", "HelloWorld");
        return map;
    }
    @Resource
    private FastDFSClientWrapper dfsClient;
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public ResponseEntity<Map<String, Object>> upload(MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, Object> map = new HashMap<>();
        String fileUrl = dfsClient.uploadFile(file);
        map.put("file_url", fileUrl);
        return ResponseEntity.ok(map);

    }
}

util工具类

java 复制代码
package com.et.fastdfs.util;

import com.et.fastdfs.constant.FastDFSConstants;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.exception.FdfsUnsupportStorePathException;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.Charset;

/**
 * Description: FastDFS文件上传下载包装类
 */
@Component
@Log4j2
public class FastDFSClientWrapper {

    @Autowired
    private FastFileStorageClient storageClient;

    /**
     * 上传文件
     * @param file 文件对象
     * @return 文件访问地址
     * @throws IOException
     */
    public String uploadFile(MultipartFile file) throws IOException {
        StorePath storePath = storageClient.uploadFile(file.getInputStream(),file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()),null);
        return getResAccessUrl(storePath);
    }

    /**
     * 将一段字符串生成一个文件上传
     * @param content 文件内容
     * @param fileExtension
     * @return
     */
    public String uploadFile(String content, String fileExtension) {
        byte[] buff = content.getBytes(Charset.forName("UTF-8"));
        ByteArrayInputStream stream = new ByteArrayInputStream(buff);
        StorePath storePath = storageClient.uploadFile(stream,buff.length, fileExtension,null);
        return getResAccessUrl(storePath);
    }

    // 封装图片完整URL地址
    private String getResAccessUrl(StorePath storePath) {
        String fileUrl = FastDFSConstants.HTTP_PRODOCOL + "://" + FastDFSConstants.RES_HOST + "/" + storePath.getFullPath();
        return fileUrl;
    }

    /**
     * 删除文件
     * @param fileUrl 文件访问地址
     * @return
     */
    public void deleteFile(String fileUrl) {
        if (StringUtils.isEmpty(fileUrl)) {
            return;
        }
        try {
            StorePath storePath = StorePath.praseFromUrl(fileUrl);
            storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
        } catch (FdfsUnsupportStorePathException e) {
            log.warn(e.getMessage());
        }
    }

    // 除了FastDFSClientWrapper类中用到的api,客户端提供的api还有很多,可根据自身的业务需求,将其它接口也添加到工具类中即可。
    // 上传文件,并添加文件元数据
    //StorePath uploadFile(InputStream inputStream, long fileSize, String fileExtName, Set<MateData> metaDataSet);
    // 获取文件元数据
    //Set<MateData> getMetadata(String groupName, String path);
    // 上传图片并同时生成一个缩略图
    //StorePath uploadImageAndCrtThumbImage(InputStream inputStream, long fileSize, String fileExtName, Set<MateData> metaDataSet);
    // 。。。
}

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

4.测试

  • 启动Spring Boot工程
  • postman上传文件测试

5.引用

相关推荐
小哇6666 分钟前
SpringBoot整合Minio
java·spring boot·spring
知其然亦知其所以然11 分钟前
深入Kafka:如何保证数据一致性与可靠性?
后端·面试·kafka
Tech Synapse19 分钟前
Java循环创建对象内存溢出怎么解决
java·开发语言·jvm
IT·陈寒20 分钟前
Kotlin vs Java:深入解析两者之间的最新差异与优劣(全面指南)
java·python·kotlin
行动π技术博客31 分钟前
spring中IOC相关介绍
java·spring·rpc
WHYBIGDATA36 分钟前
Scala中高级的函数编程
开发语言·后端·scala
吃青椒的小新41 分钟前
独一无二的设计模式——单例模式(Java实现)
java·后端·单例模式·设计模式
知识分享小能手41 分钟前
从新手到高手:Scala函数式编程完全指南,Scala 访问修饰符(6)
大数据·开发语言·后端·python·数据分析·scala·函数式编程
天才梦浪1 小时前
开源租房项目
java·项目
杰哥在此1 小时前
Java面试题:解释跨站脚本攻击(XSS)的原理,并讨论如何防范
java·开发语言·面试·编程·xss