分布式文件存储-FastDFS
介绍
FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
FastDFS体系结构
FastDFS 架构包括 Tracker server 和 Storage server。客户端请求 Tracker server 进行文件上传、下载,通过Tracker server 调度最终由 Storage server 完成文件上传和下载。
架构图
上传流程
FastDFS搭建
1.docker安装
docker pull morunchang/fastdfs
docker run -d --name tracker --net=host morunchang/fastdfs sh tracker.sh
docker run -d --name storage --net=host -e TRACKER_IP=<your tracker server address>:22122 -e GROUP_NAME=<group name> morunchang/fastdfs sh storage.sh
2.修改nginx的配置
docker exec -it storage /bin/bash
vi /data/nginx/conf/nginx.conf
添加配置内容
location /group1/M00 {proxy_next_upstream http_502 http_504 error timeout invalid_header;proxy_cache http-cache;proxy_cache_valid 200 304 12h;proxy_cache_key $uri$is_args$args;proxy_pass http://fdfs_group1;expires 30d;}
3.重启storage服务
docker restart storage
代码实现
1.maven添加依赖
<!-- fastdfs --><dependency><groupId>com.github.tobato</groupId><artifactId>fastdfs-client</artifactId><version>1.27.2</version></dependency>
2.配置文件
server:port: 7002spring:application:name: filefdfs:so-timeout: 2000 # 读取时间connect-timeout: 1000 # 连接超时时间thumb-image: # 生成缩略图height: 150 # 缩略图高度width: 150 # 缩略图宽度tracker-list: # tracker 服务器地址- 192.168.200.128:22122web-server-url: http://192.168.200.128:8080/ # storage 服务器上nginx的地址pool: # 可参考 ConnectionPoolConfig#从池中借出的对象的最大数目(配置为-1表示不限制)max-total: -1#获取连接时的最大等待毫秒数(默认配置为5秒)max-wait-millis: 5000#每个key最大连接数 key配置的是连接服务端的地址(IP+端口)连接情况,如果有连接不够用的情况可以调整以上参数max-total-per-key: 50#每个key对应的连接池最大空闲连接数max-idle-per-key: 10#每个key对应的连接池最小空闲连接数min-idle-per-key: 5#向调用者输出“连接”资源时,是否检测有效性test-on-borrow: true
3.上传代码
package com.tea.file.controller;import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.MetaData;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tea.common.entity.ResponseResult;
import com.tea.common.entity.StatusCode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;/*** @className: FastDfsController* @author: junfeng* @date: 2022/11/28**/
@RestController
@AllArgsConstructor
@RequestMapping("file")
@Slf4j
@Api(tags = "1 文件")
public class FastDfsController {private final FastFileStorageClient fastFileStorageClient;private final FdfsWebServer fdfsWebServer;/*** 上传文件*/@PostMapping("upload")@ApiOperation(value = "1.1 上传")public ResponseResult<Object> uploadFile(MultipartFile file) {String fileName = file.getOriginalFilename();// 获取文件扩展名String extension = FilenameUtils.getExtension(fileName);// 文件元数据信息Set<MetaData> metaData = new HashSet<>(4);metaData.add(new MetaData("fileName", fileName));// 上传文件StorePath storePath;try {storePath = fastFileStorageClient.uploadImageAndCrtThumbImage(file.getInputStream(), file.getSize(), extension, metaData);} catch (IOException e) {log.error(e.getMessage(), e);return ResponseResult.fail(StatusCode.ERROR);}log.info("文件上传路径:[{}]", storePath.getFullPath());String viewPath = fdfsWebServer.getWebServerUrl() + storePath.getFullPath();log.info("可访问路径:[{}]", viewPath);extension = FilenameUtils.getExtension(viewPath);String thumbPath = viewPath.replace("." + extension, "") + "_150x150." + extension;log.info("缩略图路径:[{}]", thumbPath);List<String> result = new ArrayList<>(3);result.add(viewPath);result.add(thumbPath);result.add(storePath.getFullPath());return ResponseResult.ok(result);}}
result.add(viewPath);result.add(thumbPath);result.add(storePath.getFullPath());return ResponseResult.ok(result);
}
}