FastDFS体验
由于笔者在一个项目种要用到文件上传,刚好看到网上有一篇介绍FastDFS的文件,于是就入坑用FastDFS做文件服务器尝试了一次,顺便记录下这次入坑的过程和感受。
笔者为了方便,没有下载原始的FastDFS文件包安装,而是采用的delron/fastdfs的打包好的docker安装的,而且是单机安装。另外声明以下,FastDFS没有windows版本,因此笔者的部署环境为centOS7。
一、FastDFS简介:
分布式文件服务器;
FastDFS的Docker封装包含三个部分:tracker, storage, Nginx;
FastDFS默认占用三个端口:
8888:默认是nginx代理的端口,访问上传文件的URL地址就是用的这个端口
23000:storage服务端口
22122:tracker服务端口
二、FastDFS部署:
1、拉取镜像:
1 docker pull delron/fastdfs:latest
2、创建文件存储文件夹:
1 mkdir -p /data/tracker 2 3 mkdir -p /data/storage
3、创建tracker容器:
1 docker run -id --name tracker --restart=always --net host -v /etc/localtime:/etc/localtime -v /data/tracker:/var/fdfs delron/fastdfs tracker
4、创建storage容器:
1 docker run -id --name storage --restart=always --net host -v /etc/localtime:/etc/localtime -v /data/storage:/var/fdfs -e TRACKER_SERVER="IP:22122" -e GROUP_NAME=group1 delron/fastdfs storage
5、进入storage容器内部:
1 docker exec -it 容器id bash
6、FastDFS的Nginx模块代理默认使用的是8888端口,这个端口跟其他端口冲突的可能性很大,建议把这个端口修改下,进入storage容器内部通过下面的命令进行修改:
1 1、修改storage配置: 2 vi /etc/fdfs/storage.conf 3 http.server_port=8888 //修改8888为8850 4 5 2、修改nginx配置: 6 vi /usr/local/nginx/conf/nginx.conf 7 listen 8888; //修改8888为8850 8 9 3、退出容器: 10 exit 11 12 4、重启容器: 13 docker restart 容器id 14 docker restart storage bash
7、测试:
1 1、进入容器内部; 2 3 2、进入fdfs文件夹并放一个测试文件01.jpg: 4 cd /var/fdfs 5 6 3、执行上传命令: 7 /usr/bin/fdfs_upload_file /etc/fdfs/client.conf 01.jpg 8 执行完命令后会返回一个文件的URL地址,加上前缀(http://IP:8850)就可以直接访问
三、部署常见问题:
1.创建storage容器时不能修改分组名:
这个地方有个坑点,创建Storage容器时可以参数GROUP_NAME指定分组名称,默认是group1,笔者试着将这么名称改为”group_XXX”,结果启动时从日志中可以看到说分组名称“group_XXX”是一个不合法的分组名称,看来分组名称是不能带下划线,于是笔者又将下划线去掉,改为了“groupXXX”,启动没有任何问题,上传文件也没问题,也能正常返回上传的文件地址,但是这个地址访问始终就是404,知道后来在nginx的配置文件中发现下面这个信息才恍然大悟,分组名称必须是group后面加数字,如果要改成其他形式的分组名称,nginx配置的这个地方也要改。笔者把分组名称改为默认的“group1”后就一切正常了。
2.防火墙的设置:
如果不关闭防火墙,发现其他机器对FastDFS都不能访问,关闭防火墙就可以正常访问,防火墙相关命令:
1 开启防火墙: 2 systemctl start firewalld.service 3 4 关闭防火墙: 5 systemctl stop firewalld.service 6 7 查看防火墙状态: 8 systemctl status firewalld.service
但是生产服务器关闭防火墙肯定有安全隐患,因此防火墙要开启,但是只是针对FastDFS的端口开放,命令如下:
1 sudo firewall-cmd --zone=public --add-port=23000/tcp --permanent 2 sudo firewall-cmd --zone=public --add-port=22122/tcp --permanent 3 sudo firewall-cmd --zone=public --add-port=8850/tcp --permanent
3.笔者在调试时,前端上传用的Vue的el-upload组件,设置了显示上传进度条,但是发现无论如何都不能生效,百思不得其解,于是把FastDFS换成SpringBoot自带的MultipartFile,进度条居然能显示了,很是奇怪,更奇怪的是系统部署到生产环境后,由于用的是域名访问,用FastDFS上传的居然又能显示进度条了,真奇怪。
4.FastDFS比较适合于一些小文件的传输,比如象用户图像和一些图片之类的,但是对于比较大的文件就不太适合了,笔者在调试时发现上传大文件还没有SpringBoot自带的MultipartFile上传的快(网上有说大文件可以分片上传,不过我没研究过)。
四、SpringBoot接入:
1、添加依赖:
1 <!--分布式文件存储 fastDFS--> 2 <dependency> 3 <groupId>com.github.tobato</groupId> 4 <artifactId>fastdfs-client</artifactId> 5 <version>1.26.2</version> 6 </dependency> 7 8 <!--上传下载 间接包--> 9 <dependency> 10 <groupId>commons-io</groupId> 11 <artifactId>commons-io</artifactId> 12 <version>1.3.2</version> 13 </dependency> 14 <dependency> 15 <groupId>commons-fileupload</groupId> 16 <artifactId>commons-fileupload</artifactId> 17 <version>1.3.2</version> 18 </dependency>
2、在springboot启动类中加上以下两个注解:
1 //加载fastDFS 2 @EnableMBeanExport(registration=RegistrationPolicy.IGNORE_EXISTING) 3 @Import(FdfsClientConfig.class)
3、配置application.properties文件:
1 # 配置fastdfs的连接地址等信息 2 fdfs.connect-timeout=1000 3 fdfs.so-timeout=1500 4 # 注意这个trackerList:如果是集群tracker的话以逗号分隔开就行 5 fdfs.tracker-list=localhost:22122 6 fdfs.pool.max-total=200 7 # 最大上传单个文件大小:默认1M 8 spring.servlet.multipart.max-file-size=500MB 9 # 最大置总上传的数据大小 :默认10M 10 spring.servlet.multipart.max-request-size=1024MB
4、编写controller:
1 final String fdfsWebServer = "http://localhost:8850/"; 2 3 @ApiOperation("文件上传") 4 @Async("asyncServiceExecutor") 5 @PostMapping(value = {"fileserver/action/upload"}) 6 public Response<UploadResult> uploadFile(@RequestPart("file") MultipartFile file) { 7 try { 8 //上传 9 String fileUrlPath = fastFileStorageClient.uploadFile(file.getInputStream(), file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()), null).getFullPath(); 10 11 UploadResult result = new UploadResult(); 12 result.setOriginalFilename(file.getOriginalFilename()); 13 result.setUrlPath(fdfsWebServer + fileUrlPath); 14 logger.info("文件上传成功:{}", result.toString()); 15 return Response.returnObjectSuccess(result); 16 } catch (IOException e) { 17 logger.error("读取文件流失败:" + e.getMessage(), e); 18 throw new RuntimeException("读取文件流失败:" + e.getMessage(), e); 19 } 20 } 21 22 @ApiOperation("删除文件") 23 @DeleteMapping(value = {"/fileserver/action/delete"}) 24 public Response<Boolean> deleteFile(@RequestParam("urlPath") String urlPath) { 25 //路径检查 26 String path = urlPath; 27 if (StringUtils.isEmpty(path)) { 28 logger.error("URL路径不能为空:" + path); 29 throw new RuntimeException("URL路径不能为空"); 30 } 31 if (path.startsWith(fdfsWebServer)) { 32 path = path.substring(fdfsWebServer.length()); 33 if (StringUtils.isEmpty(path)) { 34 logger.error("URL路径不合法:" + urlPath); 35 throw new RuntimeException("URL路径不合法"); 36 } 37 } 38 39 fastFileStorageClient.deleteFile(path); 40 logger.info("删除文件{}成功", urlPath); 41 return Response.returnObjectSuccess(true); 42 }
5、上传文件代码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title></head> 6 <body> 7 <form action="http://localhost:8820/fileserver/fileserver/action/upload" method="post" enctype="multipart/form-data"> 8 <input type="file" name="file" value="请选择文件"> 9 <input type="submit" value="上传"> 10 </form> 11 </body> 12 </html>
五、FastDFS清空数据及文件:
1、停止tracker、storage服务:
1 /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf stop 2 /usr/bin/fdfs_storaged /etc/fdfs/storage-defaultgroup.conf stop
2、清空存储路径文件:
1 rm -rf /defaultgroup01/fastdfs/data/
3、清空tracker和storage的base_path:
1 rm -rf /data/fastdfs/tracker/data 2 rm -rf /data/fastdfs/tracker/logs 3 rm -rf /data/fastdfs/storage/defaultgroup/data 4 rm -rf /data/fastdfs/storage/defaultgroup/logs
4、启动tracker和storage服务:
1 /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf start 2 /usr/bin/fdfs_storaged /etc/fdfs/storage-defaultgroup.conf start
六、参考资料:
https://www.cnblogs.com/yiyezhiqiuwuchen/p/13579748.html
https://zhuanlan.zhihu.com/p/136964381
https://blog.csdn.net/weixin_45295447/article/details/128234507
https://mp.weixin.qq.com/s/mdmKahEMtHdLB-1DA6xVJg
https://dandelioncloud.cn/article/details/1579811309774663681