fastdfs简介
fastdfs是一个开源的轻量级分布式文件系统, 提供了文件上传、文件下载、文件同步、文件存储等功能, 解决了大容量存储和负载均衡的问题,适合以中小文件为载体的在线服务。
由跟踪服务器tracker server、存储服务器storage server组成, 客户端请求tracker server进行文件上传、下载,tracker server调度storage server完成文件存储。
storage server
简称storage,以卷volume为单位组织, 卷与卷之间的文件是不同的,实现了分布式存储, 一卷可以由一台或多台storage组成,每台storage的文件是相同的,起到了冗余和负载均衡的作用, 当存储空间不足时,可以动态添加卷,这样就扩大了系统的容量。
tracker server
简称tracker,tracker是fastdfs的协调者,负责调度所有的storage,storage启动会连接tracker, 告知自己所属的volume等信息, 并一直保持心跳。
tracker可以扩展为tracker cluster集群服务, cluster中每个tracker都是完全对等的, 客户端在upload时可以在集群中任意选择一个tracker。
文件上传
文件上传流程: 当tracker收到客户端的upload请求时,会按照一定的策略分配一个卷volume,
选定volume后,tracker会在volume中选择一个storage返回给客户端,
客户端向storage发送upload请求,storage会为文件分配一个目录,即虚拟磁盘, 虚拟磁盘下有两级256*256的目录, storage选择一个两级目录, 并为文件生成一个fileID作为文件名存储在该两级目录下。
在springboot使用fastdfs
fastdfs依赖
pom.xml中引入,
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.27.2</version>
</dependency>
fastdfs配置
application.properties中添加,要换成自己的fastdfsIP,
fdfs.connect-timeout=60
fdfs.thumb-image.width=300
fdfs.thumb-image.height=300
fdfs.tracker-list=fastdfsIP:22122
controller
package com.example.duohoob.controller;
import java.net.URLEncoder;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
@RestController
@RequestMapping("/fastDFS")
public class FastDFSController {
@Autowired
private FastFileStorageClient fastFileStorageClient;
@RequestMapping("/upload")
public String upload(MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename();
String fileName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
StorePath storePath = fastFileStorageClient.uploadFile(file.getInputStream(), file.getSize(), fileName, null);
String fullPath = storePath.getFullPath();
return fullPath;
}
@RequestMapping("/download")
public void download(String fullPath, HttpServletRequest request, HttpServletResponse response) throws Exception {
int index = fullPath.indexOf("/");
String groupName = fullPath.substring(0, index);
String path = fullPath.substring(index + 1);
byte[] bytes = fastFileStorageClient.downloadFile(groupName, path, new DownloadByteArray());
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("下载文件名.jpg", "UTF-8"));
ServletOutputStream outputStream = response.getOutputStream();
IOUtils.write(bytes, outputStream);
}
}
|