1. FastDFS简介
FastDFS是用c语言编写的一款开源的分布式文件系统,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合中小文件(建议范围:4KB < file_size <500MB),对以文件为载体的在线服务,如相册网站、视频网站等。
2. 架构
3. 安装
如果一步步安装FastDFS以及其依赖,极其复杂,有可能你捣鼓一上午不一定能配置好!这里建议大家使用Docker一键安装,只需要把存储目录映射出来即可。
4. SpringBoot整合
4.1 引入依赖
<!-- https://mvnrepository.com/artifact/com.github.tobato/fastdfs-client -->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.27.2</version>
</dependency>
4.2 application.yml配置
# 分布式文件系统FDFS配置
fdfs:
# 读取超时时间
soTimeout: 1500
# 连接超时时间
connectTimeout: 600
# 缩略图的宽高
thumbImage:
width: 150
height: 150
#Ttracker服务配置地址列表,支持多个
trackerList:
- 121.4.233.***:22122
4.3 创建配置类
/**
* @Author wzj
* @Param
* @Description fastDFS配置类
* @Date 14:23 2021/4/14
**/
@Configuration
@Import(FdfsClientConfig.class)
//解决jmx重复注册bean的问题
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastDFSConfiguration {
}
4.4 创建工具类
/**
* @Author wzj
* @Param
* @Description fastDFS工具类
* @Date 14:23 2021/4/14
**/
@Component
public class FastdfsUtils {
public static final String DEFAULT_CHARSET = "UTF-8";
@Autowired
private FastFileStorageClient fastFileStorageClient;
/**
* 上传
*
* @param file
* @return
* @throws IOException
*/
public StorePath upload(MultipartFile file) throws IOException {
// 设置文件信息
Set<MetaData> mataData = new HashSet<>();
mataData.add(new MetaData("author", "fastdfs"));
mataData.add(new MetaData("description", file.getOriginalFilename()));
// 上传
StorePath storePath = fastFileStorageClient.uploadFile(
file.getInputStream(), file.getSize(),
FilenameUtils.getExtension(file.getOriginalFilename()),
null);
return storePath;
}
/**
* 删除
*
* @param path
*/
public void delete(String path) {
fastFileStorageClient.deleteFile(path);
}
/**
* 删除
*
* @param group
* @param path
*/
public void delete(String group, String path) {
fastFileStorageClient.deleteFile(group, path);
}
/**
* 文件下载
*
* @param path 文件路径,例如:/group1/path=M00/00/00/itstyle.png
* @param filename 下载的文件命名
* @return
*/
public void download(String path, String filename, HttpServletResponse response) throws IOException {
// 获取文件
StorePath storePath = StorePath.parseFromUrl(path);
if (StringUtils.isBlank(filename)) {
filename = FilenameUtils.getName(storePath.getPath());
}
byte[] bytes = fastFileStorageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadByteArray());
response.reset();
response.setContentType("applicatoin/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
ServletOutputStream out = response.getOutputStream();
out.write(bytes);
out.close();
}
}
4.5 创建测试类
@Controller
@RequestMapping("/fastdfs")
public class FastdfsController {
@Autowired
private FastdfsUtils fastdfsUtils;
/**
* @Author wzj
* @Param
* @param: file
* @param: request
* @param: response
* @Description 文件上传
* @Date 10:10 2021/4/14
**/
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
@ResponseBody
public String uploadFile(MultipartFile file, HttpServletRequest request, HttpServletResponse response) {
StorePath storePath = null;
try {
storePath = fastdfsUtils.upload(file);
} catch (IOException e) {
e.printStackTrace();
}
return storePath.getPath() + "=====" + storePath.getGroup() + "=====" + storePath.getFullPath();
}
/**
* @Author wzj
* @Param
* @param: path
* @param: fileName
* @param: request
* @param: response
* @Description 下载
* @Date 11:45 2021/4/14
**/
@RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
public void download(String path, String fileName, HttpServletRequest request, HttpServletResponse response) {
try {
fastdfsUtils.download(path, fileName, response);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @Author wzj
* @Param
* @param: path
* @param: request
* @param: response
* @Description 根据路径删除
* @Date 11:45 2021/4/14
**/
@RequestMapping(value = "/deleteByPath", method = RequestMethod.POST)
@ResponseBody
public void deleteByPath(String path, HttpServletRequest request, HttpServletResponse response) {
fastdfsUtils.delete(path);
}
/**
* @Author wzj
* @Param
* @param: path
* @param: group
* @param: request
* @param: response
* @Description 根据路径和分组删除
* @Date 11:46 2021/4/14
**/
@RequestMapping(value = "/deleteByPathAndBroup", method = RequestMethod.POST)
@ResponseBody
public void deleteByPathAndBroup(String path, String group, HttpServletRequest request, HttpServletResponse response) {
fastdfsUtils.delete(group, path);
}
}