FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
FastDFS 架构包括 Tracker server 和 Storage server。客户端请求 Tracker server 进行文件上传、下载,通过Tracker server 调度最终由 Storage server 完成文件上传和下载。
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添加依赖
<dependency>
<groupId>com.github.tobatogroupId>
<artifactId>fastdfs-clientartifactId>
<version>1.27.2version>
dependency>
2.配置文件
server:
port: 7002
spring:
application:
name: file
fdfs:
so-timeout: 2000 # 读取时间
connect-timeout: 1000 # 连接超时时间
thumb-image: # 生成缩略图
height: 150 # 缩略图高度
width: 150 # 缩略图宽度
tracker-list: # tracker 服务器地址
- 192.168.200.128:22122
web-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);
}
}