109
社区成员




这个作业属于哪个课程 | 2401_CS_SE_FZU |
---|---|
这个作业要求在哪里 | 软件工程实践总结&个人技术博客 |
这个作业的目标 | 回顾和总结课程内容以及个人技术总结 |
其他参考文献 | 《构建之法》 |
目录
FASTDFS 是一款开源的分布式文件系统,主要用于解决大规模文件的存储和访问问题,支持分片存储和负载均衡,适合图片、视频等大文件的上传与下载。通过与 Nginx 配合,可以实现隐藏文件存储的真实地址。
其实现在阿里云、腾讯等公司提供了很多更快、更好、更安全的文件服务,除了价钱不太友好,其他地方可谓是哪里都好。但自己搭一个分布式文件管理系统,也是有好处的。至少不会那么贵?而且如果是学习阶段也能学到更多底层的知识。
磁盘目录
说明 | 位置 |
---|---|
所有安装包 | /usr/local/src |
数据存储位置 | /home/dfs/ |
mkdir /home/dfs #创建数据存储目录
cd /usr/local/src #切换到安装目录准备下载安装包
安装libfastcommon
git clone https://github.com/happyfish100/libfastcommon.git --depth 1
cd libfastcommon/
./make.sh && ./make.sh install #编译安装
cd ../ #返回上一级目录
安装libserverframe
git clone https://github.com/happyfish100/libserverframe.git --depth 1
cd libserverframe/
./make.sh && ./make.sh install #编译安装
cd ../ #返回上一级目录
安装FastDFS
git clone https://github.com/happyfish100/fastdfs.git --depth 1
cd fastdfs/
./make.sh && ./make.sh install #编译安装
#配置文件准备
cp /usr/local/src/fastdfs/conf/http.conf /etc/fdfs/ #供nginx访问使用
cp /usr/local/src/fastdfs/conf/mime.types /etc/fdfs/ #供nginx访问使用
cd ../ #返回上一级目录
安装fastdfs-nginx-module
git clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1
cp /usr/local/src/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs
安装nginx
wget http://nginx.org/download/nginx-1.15.4.tar.gz #下载nginx压缩包
tar -zxvf nginx-1.15.4.tar.gz #解压
cd nginx-1.15.4/
#添加fastdfs-nginx-module模块
./configure --add-module=/usr/local/src/fastdfs-nginx-module/src/
make && make install #编译安装
单机部署
tracker配置
wget http://nginx.org/download/nginx-1.15.4.tar.gz #下载nginx压缩包
tar -zxvf nginx-1.15.4.tar.gz #解压
cd nginx-1.15.4/
#添加fastdfs-nginx-module模块
./configure --add-module=/usr/local/src/fastdfs-nginx-module/src/
make && make install #编译安装
storage配置
vim /etc/fdfs/storage.conf
#需要修改的内容如下
port=23000 # storage服务端口(默认23000,一般不修改)
base_path=/home/dfs # 数据和日志文件存储根目录
store_path0=/home/dfs # 第一个存储目录
tracker_server=192.168.52.1:22122 # tracker服务器IP和端口
http.server_port=8888 # http访问文件的端口(默认8888,看情况修改,和nginx中保持一致)
client测试
vim /etc/fdfs/client.conf
#需要修改的内容如下
base_path=/home/dfs
tracker_server=192.168.52.1:22122 #tracker服务器IP和端口
#保存后测试,返回ID表示成功 如:group1/M00/00/00/xx.tar.gz
fdfs_upload_file /etc/fdfs/client.conf /usr/local/src/nginx-1.15.4.tar.gz
配置nginx访问
vim /etc/fdfs/mod_fastdfs.conf
#需要修改的内容如下
tracker_server=192.168.52.1:22122 #tracker服务器IP和端口
url_have_group_name=true
store_path0=/home/dfs
#配置nginx.config
vim /usr/local/nginx/conf/nginx.conf
#添加如下配置
server {
listen 8888; ## 该端口为storage.conf中的http.server_port相同
server_name localhost;
location ~/group[0-9]/ {
ngx_fastdfs_module;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
#测试下载,用外部浏览器访问刚才已传过的nginx安装包,引用返回的ID
http://192.168.52.1:8888/group1/M00/00/00/wKgAQ1pysxmAaqhAAA76tz-dVgg.tar.gz
#弹出下载单机部署全部跑通
导入依赖
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.27.2</version>
</dependency>
分片上传文件
//上传可以断点传续的文件
public String uploadAppenderFile(MultipartFile file) throws Exception {
String fileType=getFileType(file);
String fileName=file.getOriginalFilename();
StorePath storePath=appendFileStorageClient.uploadAppenderFile(DEFAULT_GROUP, file.getInputStream(),file.getSize(),fileType);
return storePath.getPath();
}
//断点续传
public void modifyAppenderFile(MultipartFile file,String filepath,long offset) throws Exception {
appendFileStorageClient.modifyFile(DEFAULT_GROUP,filepath,file.getInputStream(),file.getSize(),offset);
}
//
public String uploadFileBySlices(MultipartFile file, String fileMd5, Integer sliceNo, Integer totalSliceNo) throws Exception {
if(file == null || sliceNo == null || totalSliceNo == null){
throw new ConditionException("参数异常!");
}
String pathKey = PATH_KEY + fileMd5;
String uploadedSizeKey = UPLOADED_SIZE_KEY + fileMd5;
//已经上传的分片数
String uploadedNoKey = UPLOADED_NO_KEY + fileMd5;
//已经上传的分片大小
String uploadedSizeStr = redisTemplate.opsForValue().get(uploadedSizeKey);
Long uploadedSize = 0L;
if(!StringUtil.isNullOrEmpty(uploadedSizeStr)){
uploadedSize = Long.valueOf(uploadedSizeStr);
}
if(sliceNo == 1){ //上传的是第一个分片
String path = this.uploadAppenderFile(file);
if(StringUtil.isNullOrEmpty(path)){
throw new ConditionException("上传失败!");
}
redisTemplate.opsForValue().set(pathKey, path);
redisTemplate.opsForValue().set(uploadedNoKey, "1");
}else{
String filePath = redisTemplate.opsForValue().get(pathKey);
if(StringUtil.isNullOrEmpty(filePath)){
throw new ConditionException("上传失败!");
}
this.modifyAppenderFile(file, filePath, uploadedSize);
redisTemplate.opsForValue().increment(uploadedNoKey);
}
// 修改历史上传分片文件大小
uploadedSize += file.getSize();
redisTemplate.opsForValue().set(uploadedSizeKey, String.valueOf(uploadedSize));
//如果所有分片全部上传完毕,则清空redis里面相关的key和value
String uploadedNoStr = redisTemplate.opsForValue().get(uploadedNoKey);
Integer uploadedNo = Integer.valueOf(uploadedNoStr);
String resultPath = "";
if(uploadedNo.equals(totalSliceNo)){
resultPath = redisTemplate.opsForValue().get(pathKey);
List<String> keyList = Arrays.asList(uploadedNoKey, pathKey, uploadedSizeKey);
redisTemplate.delete(keyList);
}
return resultPath;
}
难点 1:Nginx 配置不生效
/etc/fdfs/mod_fastdfs.conf
中的 store_path
和 tracker_server
是否配置正确,同时确保 Nginx 的工作目录与 FASTDFS 存储目录一致。难点 2:分片上传中断后无法续传