Mac系统通过Docker搭建FastDFS

Docker构建FastDFS

查找镜像

打开终端通命令查找fastdfs的镜像

docker search fastdfs

拉取镜像

在找到合适的镜像后执行命令:

docker pull delron/fastdfs

准备构建FastDFS的目录

这一步可以自己选择文件映射位置,我这里选择的是~/docker目录下

mkdir -p ~/docker/fastdfs/tracker
mkdir -p ~/docker/fastdfs/storage
chmod -R 777 ~/docker/fastdfs

构建track服务容器

常规命令:

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

Mac系统命令:

docker run -d --name tracker -p 22122:22122  -v ~/docker/fastdfs/tracker:/var/fdfs delron/fastdfs tracker

注意:
因为Mac系统网络不支持host模式,因此要使用第二种方式构建

构建storage容器

常规命令:

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

Mac系统命令:

docker run -dti --name storage -p 8888:8888 -p 23000:23000 -e TRACKER_SERVER=192.168.12.78:22122 -e GROUP_NAME=group1 -v ~/docker/fastdfs/storage:/var/fdfs delron/fastdfs storage

注意:
因为Mac系统网络不支持host模式,因此要使用第二种方式构建
TRACKER_SERVER写本机ip地址,不能使用127.0.0.1
GROUP_NAME=group1是storage的组名,若新增storage节点可以改成group2

验证FastDFS是否构建成功

在终端中输入命令,查看容器是否正常启动:

docker ps

在这里插入图片描述
打开浏览器输入输入ip地址:8888,查看是否能访问到nginx
在这里插入图片描述
若以上都能成功表示,FastDFS构建成功

测试FastDFS文件上传

1.拷贝一张图片到storage目录下

cp ~/Desktop/DSC_6716.JPG ~/docker/fastdfs/storage

在这里插入图片描述
2.进入storage容器

docker exec -it storage /bin/bash
#进入该目录
cd /etc/fdfs/

在这里插入图片描述3.上传刚刚拷贝来的图片

fdfs_upload_file /etc/fdfs/client.conf /var/fdfs/DSC_6716.JPG

在这里插入图片描述
4.在浏览器中预览图片
在这里插入图片描述

SpringBoot集成FastDFS

导入maven依赖

<dependency>
     <groupId>cn.aghost</groupId>
     <artifactId>fastdfs-client-java</artifactId>
     <version>1.29.0</version>
</dependency>

在application.yml中增加FastDFS配置

fastdfs:
  tracker-servers: 192.168.12.78:22122

增加FastDFS配置类

package com.geek.system.config.fastdfs;

import lombok.extern.slf4j.Slf4j;
import org.csource.fastdfs.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.Properties;

/**
 * @author Xiaobo
 * @ClassName FastDFSConfig
 * @Description
 * @date 2022/10/11 5:26 下午
 */
@Slf4j
@Component
public class FastDFSConfig {
    @Value("${fastdfs.tracker-servers}")
    private String trackerServers;

    @Bean
    public StorageClient storageClient(){
        try{
            Properties props = new Properties();
            props.put(ClientGlobal.PROP_KEY_TRACKER_SERVERS, trackerServers);
            ClientGlobal.initByProperties(props);

            // 链接FastDFS服务器,创建tracker和Stroage
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getTrackerServer();
            StorageServer storageServer=trackerClient.getStoreStorage(trackerServer);

            //定义Stroage客户端对象,需要使用这个对象来完成具体的文件上传,下载和删除操作
            StorageClient storageClient = new StorageClient(trackerServer,storageServer);
            return storageClient;
        }catch (Exception e){
            log.error("加载StorageClient 异常", e);
        }
        return null;
    }


}

编写FastDFS工具类

package com.geek.system.utils;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.csource.fastdfs.FileInfo;
import org.csource.fastdfs.StorageClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

/**
 * @author Xiaobo
 * @ClassName FastDFSUtil
 * @Description
 * @date 2022/10/11 5:41 下午
 */
@Slf4j
@Component
public class FastDFSUtil {

    private static StorageClient storageClient;

    @Autowired
    public void setStorageClient(StorageClient storageClient) {
        FastDFSUtil.storageClient = storageClient;
    }

    /**
     * 文件上传
     *
     * @param file
     * @return
     */
    public static String fastUpload(MultipartFile file) {
        String url = StrUtil.EMPTY;
        String ext_name = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(StrUtil.DOT) + 1);
        try {
            String[] result = storageClient.upload_file(file.getBytes(), ext_name, null);
            url = result[0] + "/" + result[1];
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传文件失败");
        }
        return url;
    }

    /**
     * 获取文件信息
     *
     * @param groupName
     * @param remoteFileName
     * @return
     */
    public static FileInfo getFile(String groupName, String remoteFileName) {
        //获取文件信息
        FileInfo fileInfo = null;
        try {
            fileInfo = storageClient.get_file_info(groupName, remoteFileName);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取文件异常");
        }
        return fileInfo;
    }


    /**
     * 文件下载
     *
     * @param downloadFileName 下载文件名称
     * @param groupName        组名
     * @param remoteFileName   远端文件名称
     * @param response
     */
    public static void downloadFile(String downloadFileName, String groupName, String remoteFileName, HttpServletResponse response) {
        try {
            byte[] buffer = storageClient.download_file(groupName, remoteFileName);
            response.reset();
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(downloadFileName, "UTF-8"));
            response.addHeader("Content-Length", "" + buffer.length);
            OutputStream ous = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream;charset=utf-8");
            ous.write(buffer);
            ous.flush();
            ous.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 删除文件
     *
     * @param groupName      组名
     * @param remoteFileName 远端文件名称
     * @return -1失败,0成功 ,2找不到文件
     */
    public static int deleteFile(String groupName, String remoteFileName) {
        int flag = -1;
        try {
            int res = storageClient.delete_file(groupName, remoteFileName);
            flag = res;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

}

编写文件上传接口

package com.geek.system.controller;

import com.geek.system.utils.FastDFSUtil;
import lombok.RequiredArgsConstructor;
import org.csource.fastdfs.FileInfo;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

/**
 * @author Xiaobo
 * @ClassName FileController
 * @Description
 * @date 2022/10/11 5:48 下午
 */
@RestController
@RequestMapping("/v1/file")
@RequiredArgsConstructor
public class FileController {

    @PostMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file) {
        // ToDo 记录数据库
        return FastDFSUtil.fastUpload(file);
    }

    @GetMapping("/get/file")
    public FileInfo getFile(@RequestParam("group_name") String groupName,
                            @RequestParam("remote_file_name") String remoteFileName) {
        return FastDFSUtil.getFile(groupName, remoteFileName);
    }

    /**
     * 下载文件
     *
     * @param groupName
     * @param remoteFileName
     * @param response
     */
    @GetMapping("/download")
    public void downloadFile(@RequestParam("group_name") String groupName,
                             @RequestParam("remote_file_name") String remoteFileName, HttpServletResponse response) {
        // todo 这里的文件名应该随机生成或者从数据库读取,文件扩展名应该从数据库获取,这里只做下载演示,因此固定写死
        String downloadFileName = "测试下载文件.JPG";

        FastDFSUtil.downloadFile(downloadFileName, groupName, remoteFileName, response);
    }

    /**
     * 删除文件
     *
     * @param groupName
     * @param remoteFileName
     * @return -1失败,0成功 ,2找不到文件
     */
    @DeleteMapping("/delete")
    public int deleteFile(@RequestParam("group_name") String groupName,
                          @RequestParam("remote_file_name") String remoteFileName) {
        return FastDFSUtil.deleteFile(groupName, remoteFileName);
    }
}

上传接口测试

在这里插入图片描述
发现控制台报错:
在这里插入图片描述
引起报错的原因:
因为mac不支持host网络模式造成的,tracker容器配置的docker内部的ip导致的连接不通
解决方法:
进入tracker容器

docker exec -it tracker /bin/bash

编辑storage.conf文件

vi /etc/fdfs/storage.conf

在这里插入图片描述
执行以命令

fdfs_monitor /etc/fdfs/storage.conf

在这里插入图片描述
退出容器,再宿主机执行命令修改网络的别名

exit #退出容器
#修改网络的别名
sudo ifconfig lo0 alias 172.17.0.1
sudo ifconfig lo0 alias 192.168.12.78

注意
设置网络别名后,所有访问172.17.0.1的都会访问到本机

还原网络设置

sudo ifconfig lo0 -alias 192.168.12.78
sudo ifconfig lo0 -alias 172.17.0.1 

在这里插入图片描述

再次测试上传文件接口

在这里插入图片描述
没有出现报错,并返回了文件的url
在这里插入图片描述

测试获取文件信息接口

在这里插入图片描述
返回了文件的基本信息

结束

至此关于FastDFS的搭建和SpringBoot的集成就都完成了,若有什么问题欢迎交流探讨,谢谢~

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值