FastDFS实用笔记 (Docker 搭建环境 + 整合 SpringBoot)

解决了大容量存储 和 负载均衡的问题,特别适合中小文件(4KB < file_size < 500MB)。如相册网站,视频网站等

FastDFS 充分考虑了冗余备份,线程扩容机制,并注重高可用。高性能等指标。使用 FastDFS 很容易搭建一套高性能的而文件服务器集群提供文件上传。下载服务

<>二、FastDFS 简介

===========================================================================

<>2.1 相关概念解释


FastDFS 文件系统由两大部分构成,一个是**客户端,**一个是服务端。

客户端是指我们的应用程序,比如我们的 Java 程序 去连接 FastDFS、操作 FastDFS。Java 程序就是一个客户端,FastDFS 提供专有 API 访问,目前提供了 C、Java 和 PHP 的几种变成语言 API。用来访问 FastDFS 文件系统

FastDFS 服务端有两个角色,代表两个服务:

  1. 跟踪器(tracker):做调度工作,在访问上起负载均衡的作用。

  2. 存储节点(storage):存储文件,完成文件管理的所有功能。

为了支持大容量,存储节点(服务器)采用了分卷(或分组)。存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的。所有卷的文件容量累加就是整个存储系统中的文件容量。一个卷可以由一个或多个存储服务器组成。一个卷下的存储服务器中的文件都是相同的。卷中多台存储服务器起到了冗余备份负载均衡

FastDFS 文件标识分为两个部分:

  1. 卷名

  2. 文件名

<>2.2 上传交互过程


  1. Client 会向 Tracker 询问存储地址,
  2. Tracker 查询到存储地址(一台可用的 Storage)返回给 Client
  3. Client 拿着地址直接和对应的 Storage 通讯,将文件上传至 Storage

<>2.3 下载交互过程


  1. Client 会向 Tracker 询问地址,并带上要查询的 文件名 和 组名
  2. Tracker 查询后会将地址(可用的 Storage)返回给 Client
  3. Client 拿着地址 和 指定 Storage 通讯并下载文件

<>2.4 FastDFS 中相关关键字解释


  • TrackerServer:跟踪服务器,主要做调度工作,在访问上起负载均衡的作用。记录 storage server 状态,是连接 client 和 Storage server 的枢纽。

  • Storage Server:存储服务器,文件和 meta data 都保存到存储服务器上

  • group:组,也称为卷,同组内服务器上的文件是完全相同的

  • 文件标识:包括两部分:组名 和 文件名(包含路径

  • meta data:文件相关属性,键值对(Key Value Pair)方式,如 width=1024,height=784

<>2.5 FastDFS 同步机制


  1. 同一组内 storage server 之间对等的,文件上传,删除等操作,可以再任意一台 storage server 运行

  2. 文件同步只在同组内的 storage server 之间进行的,采用 push 方式,及源服务器同步给目标服务器

  3. 源头数据才需要同步,备份数据不需要再次同步,否则就构成环路了

PS:上述第二条规则有个例外,就是新增加一台 storage server 时,由已有的一台 storage server 将已有的所有数据(包括源头数据 和 备份数据)同步给新增服务器

<>三、安装 FastDFS

===========================================================================

<>3.1 Linux 下安装 FastDFS


安装 fastDFS 需要分别安装 fastdfs-nginx-module,fastdfs,nginx,libfastcommon

先安装依赖环境,再安装 FastDFS

安装参考文章

安装参考文章

<>3.2 Docker 安装 FastDFS


如果学了 Docker ,我们使用 Docker 来安装就会简单很多

参考文章

下载

docker pull delron/fastdfs

查看镜像

docker images

构建 tracker 服务(跟踪服务器,实现任务调度的作用)

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

构建 storage 容器(存储服务器,提供容量和备份服务),,这里storage容器需要依赖tracker服务,传入你的tracker服务的ip地址,端口默认是22122,ip地址也就是你宿主机的ip

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

docker ps

root@VM-16-5-centos storage\]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e36862cc1e63 delron/fastdfs "/usr/bin/start1.sh ..." 9 seconds ago Up 8 seconds storage d3dfdfea80b7 delron/fastdfs "/usr/bin/start1.sh ..." 2 minutes ago Up 2 minutes tracker 进入正在工作中的 storage 容器 docker exec -it storage /bin/bash <>四、SpringBoot 整合 FastDFS ====================================================================================== <>4.1 环境准备 *** ** * ** *** 1. 一台云服务器,用来提供 FastDFS 的 tracker 服务 和 storage 服务。提供服务的地址是 IP:8888 2. SpringBoot 版本 2.3.4 PS:保证云服务器的 8888 端口(Nginx 对外提供的端口),22122 端口,23000 端口都能相互访问 <>4.2 编写 SpringBoot 程序 *** ** * ** *** pom.xml 编写,主要依赖配置如下 org.springframework.boot spring-boot-starter-web com.github.tobato fastdfs-client 1.26.5 org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine application.yml 配置 spring: application: name: fastdfs-demo servlet: multipart: max-file-size: 100MB # 最大支持文件大小 max-request-size: 100MB # 最大请求大小 enabled: true fdfs: so-timeout: 1500 # socket 连接时长 connect-timeout: 600 # 连接 tracker 服务器超时时长 ## 这两个是你服务器的 IP 地址,注意 23000 端口也要打开,阿里云服务器记得配置安全组。tracker 要和 stroage 服务进行交流 tracker-list: 服务器公网IP:22122 web-server-url: 服务器公网IP:8888 pool: jmx-enabled: false ## 生成缩略图 thumb-image: height: 500 width: 500 server: port: 80 Java 配置类,配置 FastDFS Client package com.example.config; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableMBeanExport; import org.springframework.jmx.support.RegistrationPolicy; /\*\* * @Classname FastdfsConfiguration * @Description TODO * @Date 2021/1/23 22:27 * @Created by CodingGorit * @Version 1.0 \*/ @Configuration // 导入 FastDFS-Client 组件 @EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING) // 解决 Jmx重复注册bean的问题 public class FastdfsConfiguration { } 配置静态文件访问 import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /\*\* * @Classname WebMvcConfig * @Description TODO * @Date 2021/1/23 22:55 * @Created by CodingGorit * @Version 1.0 \*/ @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry .addResourceHandler("/static/\*\*") .addResourceLocations("classpath:/static/"); } } 前端页面编写 upload.html 文件上传测试 fastDFS 工具类 package com.example.util; import com.github.tobato.fastdfs.domain.fdfs.StorePath; import com.github.tobato.fastdfs.service.FastFileStorageClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; /\*\* * @Classname FastdfsUtil * @Description TODO * @Date 2021/1/23 22:43 * @Created by CodingGorit * @Version 1.0 \*/ @Component public class FastdfsUtil { private static final Logger log = LoggerFactory.getLogger(FastdfsUtil.class); @Resource private FastFileStorageClient storageClient ; /\*\* * 上传文件 \*/ public String upload(MultipartFile multipartFile) throws Exception{ String originalFilename = multipartFile.getOriginalFilename(). substring(multipartFile.getOriginalFilename(). lastIndexOf(".") + 1); StorePath storePath = this.storageClient.uploadImageAndCrtThumbImage( multipartFile.getInputStream(), multipartFile.getSize(),originalFilename , null); return storePath.getFullPath() ; } /\*\* * 删除文件 \*/ public String deleteFile(String fileUrl) { if (StringUtils.isEmpty(fileUrl)) { log.info("fileUrl == \>\>文件路径为空..."); return "文件路径不能为空"; } try { StorePath storePath = StorePath.parseFromUrl(fileUrl); storageClient.deleteFile(storePath.getGroup(), storePath.getPath()); } catch (Exception e) { log.error(e.getMessage()); } return "删除成功"; } /\*\* * 下载文件 \*/ } 控制器类 package com.example.controller; import com.example.util.FastdfsUtil; import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; /\*\* * @Classname FileController * @Description TODO * @Date 2021/1/23 22:45 * @Created by CodingGorit * @Version 1.0 \*/ @RestController public class FileController { @Resource private FastdfsUtil fastdfsUtil; /\*\* * 文件上传 \*/ @RequestMapping(value = "/upload",headers="content-type=multipart/form-data", method = RequestMethod.POST) public Object uploadFile (@RequestParam("file") MultipartFile file){ String result ; try{ String path = fastdfsUtil.upload(file) ; if (!StringUtils.isEmpty(path)){ result = path ; } else { result = "上传失败" ; } } catch (Exception e){ e.printStackTrace() ; result = "服务异常" ; } return result; } /\*\* * 文件删除

相关推荐
数据知道35 分钟前
容器化部署:用Docker封装机器翻译模型与服务详解
docker·容器·机器翻译
_Kayo_1 小时前
node.js 学习笔记3 HTTP
笔记·学习
IT毕设实战小研3 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
一只爱撸猫的程序猿4 小时前
使用Spring AI配合MCP(Model Context Protocol)构建一个"智能代码审查助手"
spring boot·aigc·ai编程
甄超锋5 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
星星火柴9365 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
武昌库里写JAVA7 小时前
JAVA面试汇总(四)JVM(一)
java·vue.js·spring boot·sql·学习
敲上瘾7 小时前
Linux系统cgroups资源精细化控制基础
linux·测试工具·docker·压力测试·cgroups
Cx330❀7 小时前
【数据结构初阶】--排序(五):计数排序,排序算法复杂度对比和稳定性分析
c语言·数据结构·经验分享·笔记·算法·排序算法
小幽余生不加糖8 小时前
电路方案分析(二十二)适用于音频应用的25-50W反激电源方案
人工智能·笔记·学习·音视频