FastDFS的部署以及在Springboot中的应用

FastDFS

一、什么是FastDFS?

FastDFS是一个开源的轻量级分布式文件存储系统,可以供我们去完成文件的上传与下载。在FastDFS中由两部分组成,分别是tracker、Storage

  • tracker:是专门去管理storage的,在FastDFS中所有的访问都会先经过tracker,并由tracker去找有哪些storage压力小或者比较空闲,那么tracker就会返回一个storage地址供我们去上传下载
  • storage:职责就是保存上传的数据以及对数据的下载

二、使用Docker安装FastDFS

注:docker搜索镜像文件是需要联网的!!!

1、查看fastdfs都有哪些版本(搜索镜像文件)

docker search fastdfs

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dPR7U7Zt-1670471640515)(4a85625ec7d7017239bdbeee890dabb2.png)]2、拉取镜像,我这里选择的是delron/fastdfs版本(其他版本也是可以的,但是建议不要拉取太新的版本)

docker pull delron/fastdfs

拉取成功后,使用指令docker image查看镜像列表,可以看到下载的fastdfs[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-odeIJrP3-1670471640517)(0b451a8725390fd3b0e3c025bb11dac6.png)]

3、启动tracker

docker run -d --network=host --name tracker -v /home/fastdfs/docker/fastdfs/tracker:/var/fdfs delron/fastdfs tracker

docker run -d --=host --name tracker -v /home/fastdfs/docker/fastdfs/tracker:/var/fdfs delron/fastdfs tracker
–network=host:表示的是使用的网络模式为network模式
-d:表示后台启动

4、启动storage

docker run -d --network=host --name storage -e TRACKER_SERVER=ip:22122 -v /home/fastdfs/docker/fastdfs/storage:/var/fdfs -e GROUP_NAME=group1 delron/fastdfs storage

注意:

  1. ER_SERVER=ip:22122。ip要改成自己当前的ip地址
  2. GROUP_NAME=group1。storage组名可以自己设置

5、释放8888,23000,22122端口

firewall-cmd --zone=public --add-port=8888/tcp --permanent

firewall-cmd --zone=public --add-port=23000/tcp --permanent 

firewall-cmd --zone=public --add-port=22122/tcp --permanent 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8NYNcevg-1670471640518)(cecc512abf56aeeca8c6c69e8fd6b848.png)]

注意:

全部启动成功后fastdfs默认有三个端口号(放8888,23000,22122),需要在服务器中放行这三个端口号。

  • 8888:默认是nginx代理的端口 delron/fastdfs这个版本包含有nginx
  • 23000:storage服务端口
  • 22122:tracker服务端口

6、重启防火墙

# 重启之后释放的端口才会生效
systemctl reload firewalld

7、查看已放行的端口号

firewall-cmd --list-ports

三、在springboot中应用fastDFS实现文件的上传下载删除

3.1 创建springboot工程

略~

3.2 添加fastDFS依赖

   <!--分布式文件存储  fastDFS-->
        <dependency>
            <groupId>com.github.tobato</groupId>
            <artifactId>fastdfs-client</artifactId>
            <version>1.26.2</version>
        </dependency>
        
         <!--上传下载 间接包-->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.2</version>
        </dependency>

3.3 在springboot启动类中加上以下两个注解

//加载fastDFS
@EnableMBeanExport(registration= RegistrationPolicy.IGNORE_EXISTING)
@Import(FdfsClientConfig.class)

3.4 配置application.yml文件

#在application.yml中配置fastdfs的连接地址等信息

注意这个trackerList:如果是集群tracker的话以逗号分隔开就行
fdfs:
  connect-timeout: 600
  so-timeout: 1500
  trackerList: 服务器tracker的ip:22122
  thumb-image:
    width: 150
    height: 150
  pool:
    max-total: 200

fastdfs默认上传文件大小是1MB左右~所以需要我们根据自己项目的需要配置最大上传文件的大小、以及最大上传的数据大小(默认是MB)

# 最大上传单个文件大小:默认1M
spring.servlet.multipart.max-file-size=1024MB
# 最大置总上传的数据大小 :默认10M
spring.servlet.multipart.max-request-size=1024MB

3.5 书写Controller层代码–测试上传用例

package com.xgsm.fastdfsdemo;

import com.github.tobato.fastdfs.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;

@RestController
@RequestMapping("/file")
@Api(value = "fastDFs分布式文件存储 -- 文件上传下载", description = "fastDFs分布式文件存储 -- 文件上传下载")
@CrossOrigin//跨域的意思
public class FileController{

    //FastFileStorageClient 直接注入就能用 fastdsf自带的
    @Resource
    private FastFileStorageClient fastFileStorageClient;

    //fastDFS storage存储节点路径  xxxxxx:服务器ip
    private final String FASTDFSSERVERIMAGE = "http://192.168.85.129:8888/";

    /**
     * 文件上传
     * @Async开启异步
     * @return result
     */
    @ApiOperation("上传")
    @Async("asyncServiceExecutor")
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public HashMap<String, String> upload(@RequestPart("file") MultipartFile file) {
        HashMap<String, String> result = new HashMap<>();
        try {

//这里msg返回的是上传后的图片存储位置getFullPath()获取文件位置            
            result.put("msg", FASTDFSSERVERIMAGE + fastFileStorageClient.uploadFile(file.getInputStream(), file.getSize(),
                    FilenameUtils.getExtension(file.getOriginalFilename()), null).getFullPath());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

}

打开ApiPost或者Postman或Swagger-ui进行测试

返回的结果在浏览器中打开就可以看到我们上传的图片了

注意!!!!!这里很有可能会出现一个这样的问题,上传的时候,不同的文件有的时候上传成功有的时候上传失败;发生的原因大致有两种:一种是TrackerService地址配错了(但是不会出现时好时坏的情况),另一种是超时(配置fastDFS超时时间是以秒为单位,通过ClientGlabal的setG_connect_timeout(int connect_timeout)和setG_network_timeout(int network_timeout)设置超时时间是以毫秒为单位即可)。

解决措施:

1、检查TrackerService地址是否正确

2、延长超时时间

3.6 书写Controller层代码–测试删除用例

删除上传的文件,只需要将上传成功后返回的路径传递给‘删除’即可

package com.xgsm.fastdfsdemo;

import com.github.tobato.fastdfs.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;

@RestController
@RequestMapping("/file")
@Api(value = "fastDFs分布式文件存储 -- 文件上传下载", description = "fastDFs分布式文件存储 -- 文件上传下载")
@CrossOrigin//跨域的意思
public class FileController{

    //FastFileStorageClient 直接注入就能用 fastdsf自带的
    @Resource
    private FastFileStorageClient fastFileStorageClient;


    /**
     * 文件删除
     *
     * @param path
     * @return
     */
    @RequestMapping(value = "/delete", method = RequestMethod.DELETE)
    @ApiOperation("删除")
    public HashMap<String, Object> delete(@RequestParam String path) {
        HashMap<String, Object> result = new HashMap<>();
        fastFileStorageClient.deleteFile(path);
        result.put("msg", "大哥啦~~~!!,删除成功!");
        return result;
    }

}

使用ApiPost发送‘删除’请求

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KMvetDFW-1670471640521)(06dcd4c429a895699f192ba624970a29.png)]

删除成功后,再次在浏览器中访问,则会404-------删除成功

3.7 书写Controller层代码–测试下载用例

下载的时候需要根据不同的传递参数,用不同的截取方式去截取参数之后再进行赋值

package com.xgsm.fastdfsdemo;

import com.github.tobato.fastdfs.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;

@RestController
@RequestMapping("/file")
@Api(value = "fastDFs分布式文件存储 -- 文件上传下载", description = "fastDFs分布式文件存储 -- 文件上传下载")
@CrossOrigin//跨域的意思
public class FileController{

    //FastFileStorageClient 直接注入就能用 fastdsf自带的
    @Resource
    private FastFileStorageClient fastFileStorageClient;

    /**
     * 文件下载
     *
     * @param url 路径
     * @return
     */
    @RequestMapping(value = "/download", method = RequestMethod.GET)
    @ApiOperation("下载")
    public void downLoad(@RequestParam String url, HttpServletResponse response) throws IOException {
        byte[] bytes = this.downloadFile(url);
        /** TODO 这里只是为了整合fastdfs,所以写死了文件格式。需要在上传的时候保存文件名。下载的时候使用对应的格式 **/
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("sb.jpg", "UTF-8"));
        response.setCharacterEncoding("UTF-8");
        ServletOutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            outputStream.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.flush();
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

//封装的下载方法

    public byte[] downloadFile(String fileUrl) throws IOException {
//      http://192.168.85.129:8888/group1/M00/00/00/wKhVgWORP16AcJceAAAUk7NNFOw361.png
//      fileUrl:group1/M00/00/00/wKhVgWORP16AcJceAAAUk7NNFOw361.png
        String group = fileUrl.substring(0, fileUrl.indexOf("/"));
//      group需要截取的参数是:group1
        String path = fileUrl.substring(fileUrl.indexOf("/") + 1);
//      path需要截取的参数是: M00/00/00/wKhVgWORQquACgpsAALwnDncol8784.jpg       
        DownloadByteArray downloadByteArray = new DownloadByteArray();
        byte[] bytes = fastFileStorageClient.downloadFile(group, path, downloadByteArray);
        return bytes;
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P8cwAe0E-1670471640523)(4df7e6563f146d3b4ac1f1822fb88634.png)]

gitee源码地址:

https://gitee.com/xgsm/springboot-fast-dfss.git


版权声明:本文为weixin_45295447原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。