docker安装FastDFS及SpringBoot项目整合FastDFS完成文件上传和下载

一、概念

1、FastDFS是啥?

FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。
FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

在这里插入图片描述

2、包括啥?

FastDFS服务端有两个角色:跟踪器(tracker)和存储节点(storage)。

  • 跟踪器主要做调度工作,在访问上起负载均衡的作用。

  • 存储节点用来存储文件,完成文件管理的所有功能:存储、同步和提供存取接口,FastDFS同时对文件的meta data进行管理。所谓文件的meta data就是文件的相关属性,以键值对(key value pair)方式表示,如:width=1024,其中的key为width,value为1024。文件meta data是文件属性列表,可以包含多个键值对。

3、上传文件交互过程

  1. client询问tracker上传到的storage,不需要附加参数;
  2. tracker返回一台可用的storage;
  3. client直接和storage通讯完成文件上传。

4、下载文件交互过程

  1. client询问tracker下载文件的storage,参数为文件标识(卷名和文件名);
  2. tracker返回一台可用的storage;
  3. client直接和storage通讯完成文件下载。

二、Docker安装FastDFS

1、 拉取镜像

docker pull delron/fastdfs

2、构建tracker容器(跟踪服务器,起调度作用)

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

3、构建storage容器 (存储文件、文件管理)

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

4、配置nginx

默认配置不修改也可以,如果外部端口与8888冲突,则可修改下端口号

  1. 使用 docker exec -it storage /bin/bash进入storage容器
  2. 进入/usr/local/nginx/conf目录下,打开nginx.conf文件
    在这里插入图片描述
    3.进入/etc/fdfs目录,打开storage.conf文件
    在这里插入图片描述
    此处端口号和nginx监听的端口号一致

5、测试上传文件

  1. 在启动storage的时候,我们将 /mydata/fastdfs/storage 挂载到了容器中/var/fdfs的位置,此时我在宿主机上对应位置放一张图片
    在这里插入图片描述

  2. 使用docker exec -it storage /bin/bash进入storage容器

  3. 运行如下命令

     /usr/bin/fdfs_upload_file /etc/fdfs/client.conf /var/fdfs/backend.png
    

    在这里插入图片描述
    此时该图片已上传至文件系统

  4. 使用url进行访问 http://ip:port/group1/M00/00/00/rBa6BWDUSsGAbcr-AAf-SZhISJQ290.png
    在这里插入图片描述
    至此,fastdfs 安装完成.

三、SpringBoot中的使用

1.添加maven依赖

<dependency>
        <groupId>com.github.tobato</groupId>
        <artifactId>fastdfs-client</artifactId>
        <version>1.27.2</version>
</dependency>

2.在application.yml中添加配置

fdfs:
  connect-timeout: 6000 #连接超时时间
  so-timeout: 6000	      #读取超时时间
  tracker-list: 47.94.93.93:22122 #tracker服务所在的ip地址和端口号

3.上传和下载文件具体代码

import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import org.junit.platform.commons.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequestMapping("fdfs")
public class CenterUserController {

    @Autowired
    private FastFileStorageClient fastFileStorageClient;

    @PostMapping("upload")
    public String uploadFace(MultipartFile file) throws Exception {
        String path = "";
        if (file != null) {
            // 获得文件上传的文件名称
            String fileName = file.getOriginalFilename();
            if (StringUtils.isNotBlank(fileName)) {
                String fileNameArr[] = fileName.split("\\.");
                //获取文件的后缀名
                String suffix = fileNameArr[fileNameArr.length - 1];

                StorePath storePath = fastFileStorageClient.uploadFile(file.getInputStream(),
                        file.getSize(),
                        suffix, null);
                System.out.println(storePath.getFullPath());
                path = storePath.getFullPath();
            } else {
                throw new RuntimeException("文件名不能为空");
            }
        }
        return path;
    }
	
	@GetMapping("/download")
	public void downloadFile(String fileUrl, HttpServletResponse response) throws IOException {

        String group = fileUrl.substring(0, fileUrl.indexOf("/"));
        String path = fileUrl.substring(fileUrl.indexOf("/") + 1);

        String[] ss = fileUrl.split("\\.");
        String suffix = ss[ss.length-1];
        String fileName = System.currentTimeMillis()+"."+suffix;

        DownloadByteArray downloadByteArray = new DownloadByteArray();
        byte[] bytes = fastFileStorageClient.downloadFile(group, path, downloadByteArray);

        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "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();
            }
        }
    }
}

测试结果:
在这里插入图片描述
在这里插入图片描述

四、问题

1.在测试过程中,可以上传文件,但是使用url访问的时候访问不到。

这个问题困扰了我好久,最后经过排查,发现自己下载镜像不对,下载成了season/fastdfs这个镜像,按照上文内容应该是下载delron/fastdfs

其实使用season/fastdfs镜像部署完成后,我通过挂载的方式将上传文件的存储目录放在了宿主机的目录里,然后在外部再启动一个nginx,将该目录又挂载到nginx容器内部,这样的话,也可以实现使用nginx访问文件的需求。

所以我的理解就是delron/fastdfs这个版本的镜像是比较全的,含有fastdfs以及nginx以及其相关的配置,所以当tracker和storage两个容器启动之后,storage内部会自动启动nginx,所以可以使用nginx配置文件中监听的ip和port进行访问。

而season/fastdfs没有内置nginx以及其相关的配置,需要自己手动去添加并配置。需要在启动了tracker和storage容器之后,在storage容器内部下载nginx及其相关的配置并启动,才能在外部使用nginx配置文件中监听的ip和port进行访问。

2.在文中,只是实现了FastDfs单组存储配置的搭建,多组存储配置仅提供思路。

storage集群的配置
  1. 在多个服务器上部署storage容器,修改容器内的storage.conf和mod_fastdfs.conf,将tracker_server指向同一个ip:port

  2. 在一个storage容器中部署多卷,则需要修改配置mod_fastdfs.conf,

    group_count = 0 #0代表单组,非零代表多组,一般设置几就为几组
    在这里插入图片描述

tracker集群的配置
  1. 多个服务器部署tracker容器,并在tracker前使用nginx对多台tracker进行反向代理,负载均衡管理。
  2. 修改所有storage容器中的storage.conf和mod_fastdfs.conf,将其tracker_server配置成多台机器
    在这里插入图片描述

五 应用场景:

三台服务器分别做三组存储,并且需要两台tracker地址做主备关系,当一台down机后需要另外一台可以提供正常的访问连接

需要保障数据不丢失,可以分别每台存储配置两组group(相同group之间数据会自动备份) ,三台服务器group分别为:

第一台服务器:group1  group2
第二台服务器:group1 group3
第三台服务器:group2 group3

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值