FastDFS的部署以及在Springboot中的应用
admin
2024-03-27 16:43:24
0

FastDFS

一、什么是FastDFS?

FastDFS是一个开源的轻量级分布式文件存储系统,可以供我们去完成文件的上传与下载。在FastDFS中由两部分组成,分别是tracker、Storage

  • tracker:是专门去管理storage的,在FastDFS中所有的访问都会先经过tracker,并由tracker去找有哪些storage压力小或者比较空闲,那么tracker就会返回一个storage地址供我们去上传下载
  • storage:职责就是保存上传的数据以及对数据的下载

二、使用Docker安装FastDFS

注:docker搜索镜像文件是需要联网的!!!

1、查看fastdfs都有哪些版本(搜索镜像文件)

docker search fastdfs

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dPR7U7Zt-1670471640515)(4a85625ec7d7017239bdbeee890dabb2.png)]2、拉取镜像,我这里选择的是delron/fastdfs版本(其他版本也是可以的,但是建议不要拉取太新的版本)

docker pull delron/fastdfs

拉取成功后,使用指令docker image查看镜像列表,可以看到下载的fastdfs[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-odeIJrP3-1670471640517)(0b451a8725390fd3b0e3c025bb11dac6.png)]

3、启动tracker

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

docker run -d --=host --name tracker -v /home/fastdfs/docker/fastdfs/tracker:/var/fdfs delron/fastdfs tracker
–network=host:表示的是使用的网络模式为network模式
-d:表示后台启动

4、启动storage

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

注意:

  1. ER_SERVER=ip:22122。ip要改成自己当前的ip地址
  2. GROUP_NAME=group1。storage组名可以自己设置

5、释放8888,23000,22122端口

firewall-cmd --zone=public --add-port=8888/tcp --permanentfirewall-cmd --zone=public --add-port=23000/tcp --permanent firewall-cmd --zone=public --add-port=22122/tcp --permanent 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8NYNcevg-1670471640518)(cecc512abf56aeeca8c6c69e8fd6b848.png)]

注意:

全部启动成功后fastdfs默认有三个端口号(放8888,23000,22122),需要在服务器中放行这三个端口号。

  • 8888:默认是nginx代理的端口 delron/fastdfs这个版本包含有nginx
  • 23000:storage服务端口
  • 22122:tracker服务端口

6、重启防火墙

# 重启之后释放的端口才会生效
systemctl reload firewalld

7、查看已放行的端口号

firewall-cmd --list-ports

三、在springboot中应用fastDFS实现文件的上传下载删除

3.1 创建springboot工程

略~

3.2 添加fastDFS依赖

   com.github.tobatofastdfs-client1.26.2commons-iocommons-io1.3.2commons-fileuploadcommons-fileupload1.3.2

3.3 在springboot启动类中加上以下两个注解

//加载fastDFS
@EnableMBeanExport(registration= RegistrationPolicy.IGNORE_EXISTING)
@Import(FdfsClientConfig.class)

3.4 配置application.yml文件

#在application.yml中配置fastdfs的连接地址等信息注意这个trackerList:如果是集群tracker的话以逗号分隔开就行
fdfs:connect-timeout: 600so-timeout: 1500trackerList: 服务器tracker的ip:22122thumb-image:width: 150height: 150pool:max-total: 200

fastdfs默认上传文件大小是1MB左右~所以需要我们根据自己项目的需要配置最大上传文件的大小、以及最大上传的数据大小(默认是MB)

# 最大上传单个文件大小:默认1M
spring.servlet.multipart.max-file-size=1024MB
# 最大置总上传的数据大小 :默认10M
spring.servlet.multipart.max-request-size=1024MB

3.5 书写Controller层代码–测试上传用例

package com.xgsm.fastdfsdemo;import com.github.tobato.fastdfs.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;@RestController
@RequestMapping("/file")
@Api(value = "fastDFs分布式文件存储 -- 文件上传下载", description = "fastDFs分布式文件存储 -- 文件上传下载")
@CrossOrigin//跨域的意思
public class FileController{//FastFileStorageClient 直接注入就能用 fastdsf自带的@Resourceprivate FastFileStorageClient fastFileStorageClient;//fastDFS storage存储节点路径  xxxxxx:服务器ipprivate final String FASTDFSSERVERIMAGE = "http://192.168.85.129:8888/";/*** 文件上传* @Async开启异步* @return result*/@ApiOperation("上传")@Async("asyncServiceExecutor")@RequestMapping(value = "/upload", method = RequestMethod.POST)public HashMap upload(@RequestPart("file") MultipartFile file) {HashMap result = new HashMap<>();try {//这里msg返回的是上传后的图片存储位置getFullPath()获取文件位置            result.put("msg", FASTDFSSERVERIMAGE + fastFileStorageClient.uploadFile(file.getInputStream(), file.getSize(),FilenameUtils.getExtension(file.getOriginalFilename()), null).getFullPath());} catch (IOException e) {e.printStackTrace();}return result;}}

打开ApiPost或者Postman或Swagger-ui进行测试

返回的结果在浏览器中打开就可以看到我们上传的图片了

注意!!!!!这里很有可能会出现一个这样的问题,上传的时候,不同的文件有的时候上传成功有的时候上传失败;发生的原因大致有两种:一种是TrackerService地址配错了(但是不会出现时好时坏的情况),另一种是超时(配置fastDFS超时时间是以秒为单位,通过ClientGlabal的setG_connect_timeout(int connect_timeout)和setG_network_timeout(int network_timeout)设置超时时间是以毫秒为单位即可)。

解决措施:

1、检查TrackerService地址是否正确

2、延长超时时间

3.6 书写Controller层代码–测试删除用例

删除上传的文件,只需要将上传成功后返回的路径传递给‘删除’即可

package com.xgsm.fastdfsdemo;import com.github.tobato.fastdfs.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;@RestController
@RequestMapping("/file")
@Api(value = "fastDFs分布式文件存储 -- 文件上传下载", description = "fastDFs分布式文件存储 -- 文件上传下载")
@CrossOrigin//跨域的意思
public class FileController{//FastFileStorageClient 直接注入就能用 fastdsf自带的@Resourceprivate FastFileStorageClient fastFileStorageClient;/*** 文件删除** @param path* @return*/@RequestMapping(value = "/delete", method = RequestMethod.DELETE)@ApiOperation("删除")public HashMap delete(@RequestParam String path) {HashMap result = new HashMap<>();fastFileStorageClient.deleteFile(path);result.put("msg", "大哥啦~~~!!,删除成功!");return result;}}

使用ApiPost发送‘删除’请求

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KMvetDFW-1670471640521)(06dcd4c429a895699f192ba624970a29.png)]

删除成功后,再次在浏览器中访问,则会404-------删除成功

3.7 书写Controller层代码–测试下载用例

下载的时候需要根据不同的传递参数,用不同的截取方式去截取参数之后再进行赋值

package com.xgsm.fastdfsdemo;import com.github.tobato.fastdfs.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;@RestController
@RequestMapping("/file")
@Api(value = "fastDFs分布式文件存储 -- 文件上传下载", description = "fastDFs分布式文件存储 -- 文件上传下载")
@CrossOrigin//跨域的意思
public class FileController{//FastFileStorageClient 直接注入就能用 fastdsf自带的@Resourceprivate FastFileStorageClient fastFileStorageClient;/*** 文件下载** @param url 路径* @return*/@RequestMapping(value = "/download", method = RequestMethod.GET)@ApiOperation("下载")public void downLoad(@RequestParam String url, HttpServletResponse response) throws IOException {byte[] bytes = this.downloadFile(url);/** TODO 这里只是为了整合fastdfs,所以写死了文件格式。需要在上传的时候保存文件名。下载的时候使用对应的格式 **/response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("sb.jpg", "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();}}}//封装的下载方法public byte[] downloadFile(String fileUrl) throws IOException {
//      http://192.168.85.129:8888/group1/M00/00/00/wKhVgWORP16AcJceAAAUk7NNFOw361.png
//      fileUrl:group1/M00/00/00/wKhVgWORP16AcJceAAAUk7NNFOw361.pngString group = fileUrl.substring(0, fileUrl.indexOf("/"));
//      group需要截取的参数是:group1String path = fileUrl.substring(fileUrl.indexOf("/") + 1);
//      path需要截取的参数是: M00/00/00/wKhVgWORQquACgpsAALwnDncol8784.jpg       DownloadByteArray downloadByteArray = new DownloadByteArray();byte[] bytes = fastFileStorageClient.downloadFile(group, path, downloadByteArray);return bytes;}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P8cwAe0E-1670471640523)(4df7e6563f146d3b4ac1f1822fb88634.png)]

gitee源码地址:

https://gitee.com/xgsm/springboot-fast-dfss.git

相关内容

热门资讯

小棉袄电商洞察:短保零食爆火背... 当整个零食赛道还在价格战的泥潭里贴身肉搏时,长沙街头的一抹红蓝撞色,正用“新鲜”二字,悄然改写着游戏...
金价高位“吞没”!美元强势+获... 汇通财经APP讯——周三(2月26日)亚市早盘,现货黄金窄幅震荡,目前交投于5150美元/盎司附近。...
大疆反击美国禁令! 据路透社报道,中国无人机制造商大疆(DJI)周二表示,已提起诉讼,对美国联邦通信委员会(FCC)禁止...
AI算力需求刺激存储芯片股 兆... 来源:财联社 财联社2月24日讯(编辑 胡家荣)受益于海外市场消息利好,港股存储概念股走强。截至发稿...
2026年中国十大杰出品牌战略... 2026年,中国经济 将 在新质生产力驱动下稳健前行, 中国 企业竞争从产品、渠道层面升级为品牌心智...
原创 特... 一直以来,中美关系始终处于紧张状态,外部局势难以化解,特朗普却在国内遭遇了前所未有的压力。2月20日...
“红利+”指数集体涨超1%,关... 截至午间收盘,中证红利指数、国证价值100指数、国证自由现金流指数均上涨1.6%。Wind数据显示,...
ETF盘中资讯|低吸时刻?科创... 或被海外AI情绪错杀,重点布局国产AI产业链的科创人工智能ETF(589520)连跌两日,场内价格现...
哈登20分米切尔23分 骑士大... 【搜狐体育战报】北京时间2月25日NBA常规赛,主场作战的骑士以109-94击败尼克斯。阿伦19分1...
科创京津冀|十二年“聚链成群”... 2026年,京津冀协同发展迎来12周年。十二年时间,足够一个产业完成从“点”到“链”的蜕变。 早在2...
金价高位震荡!实探深圳水贝市场... 2月24日,农历正月初八,深圳水贝贵金属市场在春节“不打烊”的喧嚣后,迎来了马年首个正式工作日。尽管...
日照国资内部大调整:城投集团1... 经济导报记者 杨佳琪 2月24日,日照城投集团有限公司(下称“日照城投集团”)发布关于控股股东发生变...
南京商业大佬正式入主南通这家上... 2月24日晚间,南通上市公司*ST金灵披露公司控股股东和实际控制人变更的提示性公告。 根据《重整计划...
高特电子股权合规疑云:董事牵线... 来源丨时代商业研究院 作者丨陆烁宜 编辑丨郑琳 高校教师隐秘入股、其兄牵线融资获顾问费且获得员工持股...
大市“开门红”,白酒逆市调整,... 春节假期后首个交易日,白酒走出了“逆市”行情。 2月24日,A股大盘高开并收盘企稳4100点以上,但...
别让声誉危机,成为你融资路上的... 资本市场从来没有“温情脉脉”,只有“优胜劣汰”的残酷法则。一句广为流传的警示,道尽了企业发展的隐秘风...
钨价上涨颠覆传统逻辑,APT破... 2月25日,据中钨在线最新消息,一年来,钨价的高强度和快节奏走势,已基本颠覆了原有市场传统的交易逻辑...
波兰经济学教授:美国关税政策混... 美国最高法院20日裁定美国《国际紧急经济权力法》未授权总统大规模征收关税,美国总统特朗普当天宣布将对...
暴跌54%!非洲“一哥”跌落神... 作者:曾有为 那个曾经在非洲所向披靡、被誉为“手机中的战斗机”的传奇公司,在2026年初,交出了一份...
5个月内两次更替,涪陵榨菜迎“... 瑞财经 刘治颖 2月13日,涪陵榨菜(SZ002507)公告,提名夏强伟担任公司总经理,公司董事长、...