链接:https://pan.baidu.com/s/1EY0KPBpwaW9tpUOxSq8HcQ
提取码:lrzj
链接:https://pan.baidu.com/s/1l0zvQ-xvLtcdG_r65hh-ww
提取码:53wr
https://www.bilibili.com/video/BV1iJ411j7QY
FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。
FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
FastDFS服务端有两个角色:跟踪器(tracker)和存储节点(storage)。跟踪器主要做调度工作,在访问上起负载均衡的作用。
存储节点存储文件,完成文件管理的所有功能:就是这样的存储、同步和提供存取接口,FastDFS同时对文件的metadata进行管理。所谓文件的meta data就是文件的相关属性,以键值对(key value)方式表示,如:width=1024,其中的key为width,value为1024。文件metadata是文件属性列表,可以包含多个键值对。
跟踪器和存储节点都可以由一台或多台服务器构成。跟踪器和存储节点中的服务器均可以随时增加或下线而不会影响线上服务。其中跟踪器中的所有服务器都是对等的,可以根据服务器的压力情况随时增加或减少。
为了支持大容量,存储节点(服务器)采用了分卷(或分组)的组织方式。存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的,所有卷的文件容量累加就是整个存储系统中的文件容量。一个卷可以由一台或多台存储服务器组成,一个卷下的存储服务器中的文件都是相同的,卷中的多台存储服务器起到了冗余备份和负载均衡的作用。
在卷中增加服务器时,同步已有的文件由系统自动完成,同步完成后,系统自动将新增服务器切换到线上提供服务。
当存储空间不足或即将耗尽时,可以动态添加卷。只需要增加一台或多台服务器,并将它们配置为一个新的卷,这样就扩大了存储系统的容量。
FastDFS中的文件标识分为两个部分:卷名和文件名,二者缺一不可。
安装fastDFS分别需要安装fastdfs-nginx-moudle,fastdfs,nginx,libfastcommon
yum install -y gcc gcc-c++
yum -y install libevent
mkdir -p /fileservice/fast
cd /fileservice/fast
```
1 进入fast目录:cd /fileservice/fast
2 解压文件: tar ‐zxvf libfastcommon‐1.0.35.tar.gz
3 进入libfast文件目录:cd libfastcommon‐1.0.35
4 执行编译:./make.sh
5 安装:./make.sh install
```
网官下载很慢,看我准备的安装文件
链接:https://pan.baidu.com/s/1l0zvQ-xvLtcdG_r65hh-ww
提取码:53wr
1 yum install perl
2 yum install pcre
3 yum install pcre‐devel
4 yum install zlib
5 yum install zlib‐devel
6 yum install openssl
7 yum install openssl‐devel
1 进入fast目录:cd /fileservice/fast
2 解压文件:tar ‐zxvf fastdfs‐5.11.tar.gz
3 进入解压后的目录:cd fastdfs‐5.11
4 执行编译:./make.sh
5 安装:./make.sh install
ll /etc/init.d/ | grep fdfs
cd /etc/fdfs/
ll
查看一下
1 cp client.conf.sample client.conf
2 cp storage.conf.sample storage.conf
3 cp storage_ids.conf.sample storage_ids.conf
4 cp tracker.conf.sample tracker.conf
mkdir ‐p /home/lsz/fastdfs/tracker
cd /etc/fdfs/
vim tracker.conf
base_path=/home/yuqing/fastdfs 改为: base_path=/home/lsz/fastdfs/tracker
service fdfs_trackerd start
注意:在/home/lsz/fastdfs/tracker 目录下生成两个目录, 一个是数据,一个是日志;
cd /home/lsz/fastdfs/tracker
由于上面已经安装过FastDFS,这里只需要配置storage就好了;
cd /etc/fdfs/
group_name=group1 #配置组名
base_path=/home/yuqing/fastdfs 改为: base_path=/home/lsz/fastdfs/storage
#store存放文件的位置(store_path) store_path0=/home/yuqing/fastdfs 改为: store_path0=/home/lsz/fastdfs/storage
#如果有多个挂载磁盘则定义多个store_path,如下
#store_path1=…
#store_path2=…
#配置tracker服务器:IP
tracker_server=192.168.188.101:22122
#如果有多个则配置多个tracker
#tracker_server=192.168.188.101:22122
mkdir ‐p /home/leige/fastdfs/storage
service fdfs_storaged start
cd /etc/fdfs
vim client.conf
修改基本路径和tracker_server如下:
base_path=/home/lsz/fastdfs/storage
tracker_server=192.168.188.101:22122
注意:若tracker有多个,可以配置多个,如下:
#tracker_server=…
#tracker_server=…
如果你反正root项目可以指定目录:
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf /root/baobao.png
如果你当前目录在/etc/fdfs 可以如下:
/usr/bin/fdfs_upload_file ./client.conf ./kmd.jpg
返回:group1/M00/00/00/wKi8ZWA4nrqAcw1QACcmUui3-1g192.jpg
以上图中的文件地址: http://192.168.188.101/group1/M00/00/00/wKi8ZWA4nrqAcw1QACcmUui3-1g192.jpg
对应storage服务器上 的/home/lsz/fastdfs/storage/data/00/00/wKi8ZWA4nrqAcw1QACcmUui3-1g192.jpg 文件; 由于现在还没有和nginx整合无法使用http下载
查看图片的位置
cd /home/lsz/fastdfs/storage/data/00/00
在tracker上安装 nginx
在每个tracker上安装nginx,的主要目的是做负载均衡及实现高可用。如果只有一台tracker 可以不配置nginx。
一个tracker对应多个storage,通过nginx对storage负载均衡;
(0)注意:找到我们上传文件的位置
cd /fileservice/fast/
(1)上传fastdfsnginxmodule1.20.tar.gz 到Centos服务器上
没有上传的可以上传到 /fileservice/fast目录
(2)解压fastdfsnginxmodule1.20.tar.gz 并移动到 /usr/local目录下;
tar -zxvf fastdfs-nginx-module_v1.16.tar.gz 解压
(3)切换目录到: fastdfsnginxmodule1.20/src 目录下
(4)修改config文件,将文件中的所有 /usr/local/ 路径改为 /usr/
vim config
ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"
CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
(5)将fastdfs-nginx-module/src下的mod_fastdfs.conf拷贝至/etc/fdfs/下
(6)并修改 /etc/fdfs/mod_fastdfs.conf 的内容;
vi /etc/fdfs/mod_fastdfs.conf
tracker_server=117.48.203.125:22122
#tracker_server=192.168.172.20:22122 #(多个tracker配置多行)
url_have_group_name=true #url中包含group名称
store_path0=/home/fdfs_storage #指定文件存储路径(上面配置的store路径)
1.0 移动到fast目录
2.0 移动到 fastdfs-5.11/conf
3.0 执行复制
移动到我们上传好的位置
./configure --prefix=/opt/nginx --sbin-path=/usr/bin/nginx --add-module=/fileservice/fast/fastdfs-nginx-module-1.20/src
make && make install
cd /opt/nginx/conf
vim nginx.conf
location ~/group([0-9]) {
# root html;
# index index.html index.htm;
ngx_fastdfs_module;
}
cd /usr/bin/
./nginx #启动
因为Centos系统有防火墙,需要先关闭掉,才可以在浏览器中访问;
(1)CentOS 7.0默认使用的是firewall作为防火墙;若没有启用iptables 作为防火墙,则使用以下方式关闭防火墙:
systemctl stop firewalld.service #停止firewall
systemctl disable firewalld.service #禁止firewall开机启动
firewall-cmd --state #查看默认防火墙状态(关闭后显示notrunning,开启后显示running)
(2)若已经启用iptables作为防火墙,则使用以下方式关闭:
service iptables stop #临时关闭防火墙
chkconfig iptables off #永久关闭防火墙
(3)在谷歌浏览器中访问刚才上传的图片:
刚才上传的图片地址为:
http://192.168.188.101/group1/M00/00/00/wKi8ZWA4nrqAcw1QACcmUui3-1g192.jpg
docker run -d --restart=always --privileged=true --net=host --name=fastdfs -e IP=192.168.188.103 -e WEB_PORT=80 -v ${HOME}/fastdfs:/var/local/fdfs registry.cn-beijing.aliyuncs.com/tianzuo/fastdfs
–privileged=true是权限
–net=host是网卡
IP就是ip
web_port是端口号
-v ${HOME}/fastdfs 是容器
其中-v H O M E / f a s t d f s : / v a r / l o c a l / f d f s 是 指 : 将 {HOME}/fastdfs:/var/local/fdfs是指:将 HOME/fastdfs:/var/local/fdfs是指:将{HOME}/fastdfs这个目录挂载到容器里的/var/local/fdfs这个目录里。所以上传的文件将被持久化到${HOME}/fastdfs/storage/data里,IP 后面是自己的服务器公网ip或者虚拟机ip,-e WEB_PORT=80 指定nginx端口
删除:(如果ip錯了 直接刪除)
docker rm -f $(docker ps -aq)
//进入容器
docker exec -it fastdfs /bin/bash
//创建文件
echo "Hello FastDFS!">index.html
//测试文件上传
fdfs_test /etc/fdfs/client.conf upload index.html
http://192.168.188.103/group1/M00/00/00/wKi8Z2A51nyADpWPAAAAFIddMLE74.html
http://192.168.188.103/group1/M00/00/00/wKi8Z2A51nyADpWPAAAAFIddMLE74_big.html
点击file->project structure…->Modules
点击右上角+加号 -》New Modules
我这里项目名用fastdfsjava 截图里面用的是fastdfs-demo
修改成1.8
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0.0</version>
</dependency>
<!-- spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.25.RELEASE</version>
</dependency>
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lsz</groupId>
<artifactId>fastdfsjava</artifactId>
<version>1.0-SNAPSHOT</version>
<name>fastdfsjava</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0.0</version>
</dependency>
<!-- spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.25.RELEASE</version>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
connect_timeout=30
network_timeout=60
base_path=/home/fastdfs
#改为自己服务器的ip
tracker_server=192.168.188.103:22122
log_level=info
use_connection_pool = false
connection_pool_max_idle_time = 3600
load_fdfs_parameters_from_tracker=false
use_storage_id = false
storage_ids_filename = storage_ids.conf
http.tracker_server_port=80
package com.lsz;
import org.csource.common.MyException;
import org.csource.fastdfs.*;
import org.springframework.core.io.ClassPathResource;
import java.io.IOException;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args ) throws IOException, MyException {
String uploadFilePath="C:/Users/dell/Desktop/作业/ps/P8/1.jpg";
//得到当前conf的绝对路径
String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();
// 1、加载配置文件,配置文件中的内容就是 tracker 服务的地址。
ClientGlobal.init(filePath);
// 2、创建一个 TrackerClient 对象。直接 new 一个。
TrackerClient trackerClient = new TrackerClient();
// 3、使用 TrackerClient 对象创建连接,获得一个 TrackerServer 对象。
TrackerServer trackerServer = trackerClient.getConnection();
// 4、创建一个 StorageServer 的引用,值为 null
StorageServer storageServer = null;
// 5、创建一个 StorageClient 对象,需要两个参数 TrackerServer 对象、StorageServer 的引用
StorageClient storageClient = new StorageClient(trackerServer, storageServer);
// 6、使用 StorageClient 对象上传图片。
//扩展名不带“.”
// String[] strings = storageClient.upload_file("C:/Users/LJH/Pictures/Camera Roll/bj1.jpg", "jpg",
// null);
String[] strings = storageClient.upload_file( filePath , "jpg",
null);
// 7、返回数组。包含组名和图片的路径。
for (String string : strings) {
System.out.println(string);
}
System.out.println("上传成功");
}
}
选中+号New Module 然后next
修改 然后next
选中如下 NEXT Finish 搞定
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
fastdfs:
connect_timeout_in_seconds: 30
network_timeout_in_seconds: 60
charset: UTF-8
tracker_servers: 117.48.203.125:22122 #多个 trackerServer中间以逗号分隔
package com.lsz.util;
import org.apache.commons.lang3.StringUtils;
import org.csource.fastdfs.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
import java.util.Map;
@Component
public class UploadService{
@Value("${fastdfs.tracker_servers}")
private String tracker_servers;
@Value("${fastdfs.connect_timeout_in_seconds}")
private int connect_timeout;
@Value("${fastdfs.network_timeout_in_seconds}")
private int network_timeout;
@Value("${fastdfs.charset}")
private String charset;
public Map<String,Object> upload(MultipartFile multipartFile) {
if (multipartFile == null) {
throw new RuntimeException("文件不能为空");
}
// 上传至fastDFS, 返回文件id
String fileId = this.fdfsUpload(multipartFile);
if (StringUtils.isEmpty(fileId)) {
System.out.println("上传失败");
throw new RuntimeException("上传失败");
}
Map<String, Object> map=new HashMap<>();
map.put("code",200);
map.put("msg","上传成功");
map.put("fileId",fileId);
return map;
}
/**
* 上传至fastDFS
* @param multipartFile
* @return 文件id
*/
private String fdfsUpload(MultipartFile multipartFile) {
// 1. 初始化fastDFS的环境
initFdfsConfig();
// 2. 获取trackerClient服务
TrackerClient trackerClient = new TrackerClient();
try {
TrackerServer trackerServer = trackerClient.getConnection();
// 3. 获取storage服务
StorageServer storeStorage = trackerClient.getStoreStorage(trackerServer);
// 4. 获取storageClient
StorageClient1 storageClient1 = new StorageClient1(trackerServer, storeStorage);
// 5. 上传文件 (文件字节, 文件扩展名, )
// 5.1 获取文件扩展名
String originalFilename = multipartFile.getOriginalFilename();
String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
// 5.2 上传
String fileId = storageClient1.upload_file1(multipartFile.getBytes(), extName, null);
return fileId;
} catch (Exception e) {
System.out.println(e);
return null;
}
}
/**
* 初始化fastDFS的环境
*/
private void initFdfsConfig() {
try {
ClientGlobal.initByTrackers(tracker_servers);
ClientGlobal.setG_connect_timeout(connect_timeout);
ClientGlobal.setG_network_timeout(network_timeout);
ClientGlobal.setG_charset(charset);
} catch (Exception e) {
System.out.println(e);
}
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("upload")
public class UploadController {
@Autowired
private UploadService uploadService;
@RequestMapping("doUpload")
@ResponseBody
public Map<String,Object> doUpload(MultipartFile mf){
System.out.println(mf.getOriginalFilename());
Map<String, Object> map = uploadService.upload(mf);
return map;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>文件上传</h1>
<hr/>
<form class="" method="post" enctype="multipart/form-data" action="upload/doUpload">
<input type="file" class="mf" name = "mf"/>
<input type="submit" value="上传"/>
</form>
</body>
</html>
选中+号New Module 然后next
修改这里是的项目名应该是fastdfs-springboot2 然后next
选中如下 NEXT Finish 搞定
<!-- https://mvnrepository.com/artifact/com.github.tobato/fastdfs-client -->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.7</version>
</dependency>
fdfs:
so-timeout: 2500 # 读取时间
connect-timeout: 600 # 连接超时时间
thumb-image: # 缩略图
width: 100
height: 100
tracker-list: # tracker服务配置地址列表
- 192.168.188.103:22122 #换成你的ip
upload:
base-url: http://192.168.188.103/ #换成你的饿ip
allow-types:
- image/jpeg
- image/png
- image/bmp
注入FastFileStorageClient后,可以直接调用其uploadFile(),比上一种方法省去了手动设置配置信息,也不需要自己建立tracker连接、获取storage、再获得storageClient这些准备工作。
@ConfigurationProperties(prefix = "upload")
@Data
public class UploadProperties {
private String baseUrl;
private List<String> allowTypes;
}
@Service
@EnableConfigurationProperties(UploadProperties.class)
public class UploadService {
private Log log= LogFactory.getLog(UploadService.class);
@Autowired
private FastFileStorageClient storageClient;
@Autowired
private UploadProperties prop;
public String uploadImage(MultipartFile file) {
// 1、校验文件类型
String contentType = file.getContentType();
if (!prop.getAllowTypes().contains(contentType)) {
throw new RuntimeException("文件类型不支持");
}
// 2、校验文件内容
try {
BufferedImage image = ImageIO.read(file.getInputStream());
if (image == null || image.getWidth() == 0 || image.getHeight() == 0) {
throw new RuntimeException("上传文件有问题");
}
} catch (IOException e) {
log.error("校验文件内容失败....{}", e);
throw new RuntimeException("校验文件内容失败"+e.getMessage());
}
try {
// 3、上传到FastDFS
// 3.1、获取扩展名
String extension = StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
// 3.2、上传
StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(), extension, null);
// 返回路径
return prop.getBaseUrl() + storePath.getFullPath();
} catch (IOException e) {
log.error("【文件上传】上传文件失败!....{}", e);
throw new RuntimeException("【文件上传】上传文件失败!"+e.getMessage());
}
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("upload")
public class UploadController {
@Autowired
private UploadService uploadService;
@RequestMapping("doUpload")
@ResponseBody
public Map<String,Object> doUpload(MultipartFile mf){
System.out.println(mf.getOriginalFilename());
Map<String, Object> upload =new HashMap<>();
String path = this.uploadService.uploadImage(mf);
upload.put("path",path);
return upload;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>文件上传</h1>
<hr/>
<form class="" method="post" enctype="multipart/form-data" action="upload/doUpload">
<input type="file" class="mf" name = "mf"/>
<input type="submit" value="上传"/>
</form>
</body>
</html>