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; } /\*\* * 文件删除

相关推荐
eternal__day14 分钟前
Spring Boot 实现验证码生成与校验:从零开始构建安全登录系统
java·spring boot·后端·安全·java-ee·学习方法
宛如昨晚没早睡3 小时前
SpringBoot的自动配置和起步依赖原理
spring boot
源码云商3 小时前
Spring Boot + Vue 实现在线视频教育平台
vue.js·spring boot·后端
敦普水性工业漆4 小时前
汽车紧固件防腐3.0时代:敦普水性漆用无铬锌铝涂层定义「零氢脆」标准
笔记·汽车
leo·Thomas4 小时前
NetBox Docker 全功能部署方案(Ubuntu 22.04 + Docker)
运维·ubuntu·docker·容器·资产管理
TUTO_TUTO6 小时前
【AWS+Wordpress】将本地 WordPress 网站部署到AWS
笔记·学习·云计算·aws
Micro麦可乐6 小时前
最新Spring Security实战教程(十四)OAuth2.0精讲 - 四种授权模式与资源服务器搭建
java·服务器·spring boot·spring·spring security·oauth2·oauth2授权
大溪地C7 小时前
CSS详细学习笔记
css·笔记·学习
caihuayuan57 小时前
[数据库之十四] 数据库索引之位图索引
java·大数据·spring boot·后端·课程设计
chennalC#c.h.JA Ptho7 小时前
Centos系统详解架构详解
linux·经验分享·笔记·系统架构·系统安全