快速搞懂如何使用docker+FastDFS+SpringBoot实现分布式文件上传系统

安装FastDFS

centos7安装FastDFS非常麻烦,而且容易出错?
java实现文件上传到服务器,没思路?
这篇文章详细介绍如何使用docker+FastDFS+SpringBoot实现分布式文件上传系统。

linux安装FastDFS可参看:https://blog.csdn.net/qq_42937522/article/details/101114411

centos7安装docker可参看:centos7安装docker及docker常用命令

FastDFS简介

FastDFS是一个开源的分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。可以说它就是为互联网而生,为大数据而生的。

FastDFS服务端有两个角色:跟踪器(tracker)存储节点(storage)。跟踪器主要做调度工作,在访问上起负载均衡的作用。 存储节点存储文件,完成文件管理的所有功能:存储、同步和提供存取接口,FastDFS同时对文件的meta data进行管理。跟踪器和存储节点都可以由多台服务器构成。跟踪器和存储节点中的服务器均可以随时增加或下线而不会影响线上服务。其中跟踪器中的所有服务器都是对等的,可以根据服务器的压力情况随时增加或减少。

docker安装FastDFS

1.下载最新的FastDFS镜像
docker pull delron/fastdfs
2.提前建好需要挂载进容器的目录

使用mkdir命令,新建/data/fastdfs/tracker目录和/data/fastdfs/storage目录。

3.运行容器并挂载目录

需要分别运行tracker和storage两个容器。

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

TRACKER_SERVER是tracker的ip和端口,端口一般是22122,ip需要换成自己的。

4.使用docker ps查看运行中的容器是否有tracker和storage

在这里插入图片描述
如果有,说明运行成功。

5.测试上传

①进入容器

docker exec -it storage /bin/bash

②默认集成了nginx,可以查看nginx的配置

cd /usr/local/nginx/conf
cat nginx.conf

在这里插入图片描述
③查看storage的配置文件

cd /etc/fdfs
cat storage.conf

在这里插入图片描述
④storage的配置文件与nginx的端口一致,说明没有问题
默认端口为8888

⑤测试上传文件
将一张图片放到我们的挂载目录/data/fastdfs/storage下,默认会在/var/fdfs下显示,因为有挂载映射。

cd /var/fdfs
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf test.jpg

在这里插入图片描述
可通过返回的组信息,查看图片

浏览器输入路径:ip:8888/group1/M00/00/00/rBEACF7I6SaAShxXAAXE1JKRK9c745.jpg
即可访问

在这里插入图片描述

SpringBoot+FastDFS搭建分布式文件上传系统

1.引入依赖
<dependency>
    <groupId>com.github.tobato</groupId>
    <artifactId>fastdfs-client</artifactId>
    <version>1.26.1-RELEASE</version>
</dependency>
2.在application.yml进行配置
#FastDFS相关配置
fdfs:
  so-timeout: 1501 # 超时时间
  connect-timeout: 601 # 连接超时时间
  thumb-image: # 缩略图设置
    width: 60
    height: 60
  tracker-list: # tracker地址:你的虚拟机服务器地址+端口(默认是22122- ip:22122

ip需要替换成自己的ip地址

3.编写FastDFS的配置类

主要解决以下错误,如果没有,启动时会报错

***************************
APPLICATION FAILED TO START
***************************

Description:

Field storageClient in com.blog.module.upload.service.UploadService required a bean of type 'com.github.tobato.fastdfs.service.FastFileStorageClient' that could not be found.

The injection point has the following annotations:
	- @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'com.github.tobato.fastdfs.service.FastFileStorageClient' in your configuration.
/**
 * Description: FastDFS配置类
 *
 * 解决jmx重复注册bean的问题
 **/

@Configuration
@Import(FdfsClientConfig.class)
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastClientImporterConfig {

}
4.编写UploadController接口
@RestController
@RequestMapping("/api/file")
public class UploadController {

    @Autowired
    private UploadService uploadService;

    /**
     * 功能描述:图片上传
     *  请求参数:文件,参数名是file,SpringMVC会封装为一个接口:MultipartFile
     *   返回结果:上传成功后得到的文件的url路径,也就是返回String
     * @param file
     * @return 图片的url地址
     */
    @PostMapping("/upload")
    public ResponseEntity<String> uploadImage(@RequestParam("file") MultipartFile file{
        String url = this.uploadService.upload(file);
        //判断url是否为空
        if(StringUtils.isBlank(url)){
            return ResponseEntity.badRequest().build();
        }
        return ResponseEntity.status(HttpStatus.CREATED).body(url);
    }
    
    @DeleteMapping("/")
    public ResponseEntity<Void> deleteImage(@RequestParam("filePath") String filePath){
        System.out.println(filePath);
        this.uploadService.deleteImage(filePath);
        return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
    }
}

5.编写UploadService
@Slf4j
@Service
public class UploadService {

    @Autowired
    private FastFileStorageClient storageClient;

    private static final List<String> CONTENT_TYPES = Arrays.asList("image/jpeg", "image/gif","image/jpg","image/png");

    /**
     *  图片上传
     * @param file
     * @return
     */
    public String upload(MultipartFile file) {

        String originalFilename = file.getOriginalFilename();
        // 校验文件的类型
        String contentType = file.getContentType();
        if (!CONTENT_TYPES.contains(contentType)){
            // 文件类型不合法,直接返回null
            log.info("文件类型不合法:{}", originalFilename);
            return null;
        }

        try {
            // 校验文件的内容
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            if (bufferedImage == null){
                log.info("文件类型不合法:{}", originalFilename);
                return null;
            
            // 保存到服务器,会默认上传到application.yml配置的ip的服务器
            String ext = StringUtils.substringAfterLast(originalFilename, ".");
            StorePath storePath = this.storageClient.uploadFile(file.getInputStream(), file.getSize(), ext, null);

            // 生成url地址,返回
            return "http://ip:8888/" + storePath.getFullPath();
        } catch (IOException e) {
            log.info("服务器内部错误:{}", originalFilename);
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 功能描述: 删除图片
     *
     * @param
     * @author jiaoqianjin
     * Date: 2020/5/7 21:34
     */
    public void deleteImage(String filePath) {
        if (StringUtils.isEmpty(filePath)) {
            throw new BaseException("图片路径不能为空");
        }
        //执行删除图片
       this.storageClient.deleteFile(filePath);
    }
}

6.配置完成,可以利用postman进行测试
postman文件请求

①填写Headers
Key:Content-Type
Value:multipart/form-data
在这里插入图片描述
②填写body
在这里插入图片描述
③发送请求
在这里插入图片描述
可通过返回的路径直接进行访问。

猜你喜欢

转载自blog.csdn.net/qq_42937522/article/details/106302442