基于FastDFS创建存储服务器并在SpringBoot中使用

概述

最近在编写一个项目之中,有一个上传用户头像的功能,本想使用网上现有的图床一类的接口,但想了想何不自己搭建一个呢。于是了解到FastDFS,它是一个轻量级的分布式存储系统。放我这个学生机上感觉有点委屈它了23333.

网上浏览了一下,有点讨厌下载、打包、配置的流程,想偷懒...于是抄起了docker。

安装

拉取镜像

docker pull delron/fastdfs

创建tracker调度器

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

创建存储服务,自己需要写一下自己服务器的IP地址。

docker run -d --network=host --name storage -e TRACKER_SERVER=服务器IP地址:22122 -v /var/fdfs/storage:/var/fdfs -e GROUP_NAME=group1 delron/fastdfs storage

自此,便以容器形式启动成功了,之后我们还需要更改一个配置。

首先进入调度器容器之中。将「/etc/fdfs/client.conf」 配置文件中的「tracker_server=」配置项更改为「自己的IP地址 + 22122」

到这里已经安装完毕。需要注意的是,如果你使用了宝塔,则需要在「宝塔面板-安全」中将「8888、22122、23000」三个端口进行开放。如果你的服务器是阿里云或者腾讯云的服务器,还需要在你服务器的安全组之中开放这三个端口。

集成到Springboot

上述已完成安装,那么就进行代码层面。

pom

 <!-- FastDFS依赖 -->
 <dependency>
     <groupId>com.github.tobato</groupId>
     <artifactId>fastdfs-client</artifactId>
     <version>1.26.5</version>
 </dependency>

工具类

@Component
public class FileDfsUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(FileDfsUtil.class);
    @Resource
    private FastFileStorageClient storageClient;

    /**
     * 上传文件
     */
    public String upload(MultipartFile file) throws Exception {
        StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()), null);
        return storePath.getFullPath();
    }

    /**
     * 删除文件
     */
    public void deleteFile(String fileUrl) {
        if (StringUtils.isEmpty(fileUrl)) {
            LOGGER.info("fileUrl == >>文件路径为空...");
            return;
        }
        try {
            StorePath storePath = StorePath.parseFromUrl(fileUrl);
            storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
        } catch (Exception e) {
            LOGGER.info(e.getMessage());
        }
    }
}

上传接口

通过以下代码,当我们上传了对应的文件之后便会获得文件在服务器上的路径。我们可以在浏览器上以「服务器IP地址:8888(端口)」 + 「返回的路径」为地址得到这张图片。

/**
 * 图片上传
 * @param file
 * @return
 */
@ApiOperation(value = "上传文件", notes = "存储服务器仅支持以下格式:png、gif、jpg、jpeg、bmp")
@PostMapping("/upload")
public AjaxResult uploadFile(@RequestParam("file") MultipartFile file) {

    String fileName = file.getName();
    String fileFormat = fileName.substring(fileName.indexOf("."));
    if(!fileFormat.contains("png") && !fileFormat.contains("gif")
            && !fileFormat.contains("jpg")
            && !fileFormat.contains("jpeg")
            && !fileFormat.contains("bmp")){
        return AjaxResult.error("存储服务器仅支持以下格式:png、gif、jpg、jpeg、bmp");
    }

    try {
        String path = fileDfsUtil.upload(file);
        if (!StringUtils.isEmpty(path)) {
            //返回的是根目录,因此要加上图片服务器域名
            return AjaxResult.success(path);
        }
    } catch (Exception e) {
        return AjaxResult.error("存储服务出现异常");
    }
    return AjaxResult.error();
}

反向代理

上述已经叙述完毕所有的代码,这个时候是有一个问题的——我们不可能以「服务器IP地址:8888」 + 「返回的路径」为资源地址这种形式,太不优雅啦,一般我们要对其做一层反向代理,我便将这个存储服务器映射到了「img.ku-m.cn」这个地址之上。

域名解析

首先,我们需要通过你的域名服务商去解析一下。将「img」这个二级域名对应到你的服务器。这里不再撰述。

Nginx反向代理

前一步完成之后,当你访问你的二级域名「img」的时候,请求就会来到你的服务器之上,这个时候我们在Nginx配置文件中加上以下配置。在以前的博文中,我也记录过这种方式:nginx反向代理映射Node项目

server {
    client_max_body_size 20M; 
    listen  80;  
    server_name img.ku-m.cn; 
    location / {  
     proxy_pass http://127.0.0.1:8888;  
    }  
}