FastDFS是用 c 语言编写的一款开源的分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。
目录
前言
FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
FastDFS 架构包括 Tracker server 和 Storage server。客户端请求 Tracker server 进行文件上传、下载,通过Tracker server 调度最终由 Storage server 完成文件上传和下载。
一、FastDFS搭建
1.拉取镜像
docker pull morunchang/fastdfs
2.运行tracker
docker run -d --name tracker --net=host morunchang/fastdfs sh tracker.sh
3.运行storage
docker run -d --name storage --net=host -e TRACKER_IP=192.168.243.128:22122 -e GROUP_NAME=group1 morunchang/fastdfs sh storage.sh
-
使用的网络模式是–net=host, 192.168.243.128是宿主机的IP
-
group1是组名,即storage的组
-
如果想要增加新的storage服务器,再次运行该命令,注意更换 新组名
4.配置Nginx
Nginx在这里主要提供对FastDFS图片访问的支持,Docker容器中已经集成了Nginx,我们需要修改nginx的配置,进入storage的容器内部,修改nginx.conf
docker exec -it storage /bin/bash
vi /etc/nginx/conf/nginx.conf
添加以下内容
location ~ /M00 {
root /data/fast_data/data;
ngx_fastdfs_module;
}
5.设置禁止浏览器缓存:
add_header Cache-Control no-store;
退出容器
exit
重启storage容器
docker restart storage
开启启动设置,docker启动时
docker update --restart=always tracker
docker update --restart=always storage
二、springBoot搭建文件存储微服务
1.pom.xml依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.7-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>fastDfs</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>fastDfs</name>
<description>fastDfs</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- fastDFS依赖-->
<dependency>
<groupId>cn.bestwu</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
</project>
2.配置
在resources文件夹下创建application.yml
spring:
servlet:
multipart:
#max-file-size是单个文件大小
max-file-size: 5MB
#max-request-size是设置总上传的数据大小
max-request-size: 10MB
application:
name: file
server:
port: 9002
#tracker服务器IP地址和端口号
FILE_SERVER_URL: http://192.168.243.128:8080/
在resources文件夹下创建fasfDFS的配置文件fdfs_client.conf
#tracker服务器IP地址和端口号
tracker_server=192.168.243.128:22122
3.创建一个FastDFSClient的工具类
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
public class FastDFSClient {
private TrackerClient trackerClient = null;
private TrackerServer trackerServer = null;
private StorageServer storageServer = null;
private StorageClient1 storageClient = null;
public FastDFSClient(String conf) throws Exception {
if (conf.contains("classpath:")) {
conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
}
ClientGlobal.init(conf);
trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageServer = null;
storageClient = new StorageClient1(trackerServer, storageServer);
}
/**
* 上传文件方法
* <p>Title: uploadFile</p>
* <p>Description: </p>
*
* @param fileName 文件全路径
* @param extName 文件扩展名,不包含(.)
* @param metas 文件扩展信息
* @return
* @throws Exception
*/
public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception {
String result = storageClient.upload_file1(fileName, extName, metas);
return result;
}
public String uploadFile(String fileName) throws Exception {
return uploadFile(fileName, null, null);
}
public String uploadFile(String fileName, String extName) throws Exception {
return uploadFile(fileName, extName, null);
}
/**
* 上传文件方法
* <p>Title: uploadFile</p>
* <p>Description: </p>
*
* @param fileContent 文件的内容,字节数组
* @param extName 文件扩展名
* @param metas 文件扩展信息
* @return
* @throws Exception
*/
public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception {
String result = storageClient.upload_file1(fileContent, extName, metas);
return result;
}
public String uploadFile(byte[] fileContent) throws Exception {
return uploadFile(fileContent, null, null);
}
public String uploadFile(byte[] fileContent, String extName) throws Exception {
return uploadFile(fileContent, extName, null);
}
/**
* 根据groupName和文件名获取文件信息。
*
* @param groupName
* @param remoteFileName
* @return
* @throws MyException
* @throws IOException
*/
public FileInfo getFile(String groupName, String remoteFileName) throws MyException, IOException {
return storageClient.get_file_info(groupName, remoteFileName);
}
/**
* 下载文件
*
* @param groupName
* @param remoteFileName
* @return
* @throws MyException
* @throws IOException
*/
public InputStream downFile(String groupName, String remoteFileName) throws MyException, IOException {
byte[] fileByte = storageClient.download_file(groupName, remoteFileName);
InputStream ins = new ByteArrayInputStream(fileByte);
return ins;
}
public byte[] downFile1(String groupName, String remoteFileName) throws MyException, IOException {
return storageClient.download_file(groupName, remoteFileName);
}
/**
* 删除文件
*
* @param groupName
* @param remoteFileName
* @throws Exception
*/
public boolean deleteFile(String groupName, String remoteFileName) throws Exception {
int i = storageClient.delete_file(groupName, remoteFileName);
return i == 0 ? true : false;
}
public boolean deleteFile(String fileId) throws Exception {
int i = storageClient.delete_file1(fileId);
return i == 0 ? true : false;
}
}
4.创建controller层
@GetMapping("/downFile")
public void downFile(@RequestParam("groupName") String groupName, @RequestParam("remoteFileName") String remoteFileName){
uploadService.downloadFile(groupName, remoteFileName);
}
创建service层
public void downloadFile(String groupName, String remoteFileName) {
try {
int i = remoteFileName.lastIndexOf(".");
String extName = remoteFileName.substring(i);
//创建一个FastDFS客户端
FastDFSClient fastDFSClient = new FastDFSClient("classpath:fdfs_client.conf");
//使用fastDFSClient工具类下载文件
byte[] result = fastDFSClient.downFile1(groupName, remoteFileName);
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletResponse response = servletRequestAttributes.getResponse();
response.setContentType("application/octet-stream;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("文件" + extName, "utf-8"));
OutputStream ouputStream = response.getOutputStream();
ouputStream.write(result);
ouputStream.flush();
ouputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
5.创建启动类FastDfsApplication
package com.example.fastdfs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class FastDfsApplication {
public static void main(String[] args) {
SpringApplication.run(FastDfsApplication.class, args);
System.out.println("=============FastDfs启动成功======================");
}
}