分布式文件系统----FastDFS
FastDFS
- 1、分布式文件系统
- 1.1 FastDFS简介
- 1.2 FastDFS整体架构
- 1.3 FastDFS的存储策略
- 1.4 FastDFS的上传过程
- 1.5 FastDFS的文件同步
- 1.6 FastDFS的文件下载
- 2、FastDFS环境搭建
- 2.1 FastDFS安装
- 2.1.1 **安装前的准备**
- (1) 检查Linux上是否安装了 gcc、libevent、libevent-devel
- (2) 如果没有安装,则需进行安装
- 2.1.2 **安装 libfastcommon 库**
- (1) 将下载好的libfastcommon文件上传到Linux(/home/)
- (2) 解压下载下来的tar.gz压缩包到当前目录
- (3) 切换到解压后的libfastcommon目录
- (4) 执行make脚本进行编译
- (5) 执行make install进行安装
- 2.1.3 安装FastDFS
- (1) 将下载好的FastDFS文件上传到Linux(/home/)
- (2) 解压下载下来的tar.gz压缩包到当前目录
- (3) 切换到解压后FastDFS的目录
- (4) 执行make脚本进行编译
- (5) 执行make install进行安装
- (6) 查看安装后的效果
- A、 查看FastDFS相关的可执行程序
- B、 查看FastDFS的配置文件
- (7) 另外注意需要把解压后的fastdfs-5.11/conf目录下的两个文件拷贝到/etc/fdfs/ ,否则后续会有很多奇怪问题不好解决
- 2.2 FastDFS配置文件详解
- 1. 去掉/etc/fdfs/目录下FastDFS配置文件的后缀名
- 2. 修改tracker.conf文件
- 3. 修改storage.conf文件
- 4. 在Linux服务器上创建上面指定的目录
- 5. 然后启动FastDFS
- 2.3 FastDFS启动
- 1. 启动FastDFS的tracker服务
- 2. 启动FastDFS的storage服务
- 3. 查看启动进程
- 4. 查看storage是否已经注册到了tracker下
- 5. 首次启动storage后,会在配置的路径下创建存储文件的目录
- 2.4 FastDFS重启与FastDFS关闭
- 2.4.1 FastDFS重启
- 2.4.2 FastDFS关闭
- 2.5 FastDFS测试
- 2.5.1 测试文件上传
- 2.5.2 测试文件删除
- 3、分布式文件系统FastDFS的HTTP访问
- 3.1 前期准备工作
- 3.2 安装Nginx并且添加fastDFS模块
- 1. 将Nginx的tar包上传到Linux上
- 2. 解压上传的Nginx文件
- 3. 切换至解压后的Nginx主目录,执行配置操作
- 4. 执行命令进行编译
- 5. 执行命令进行安装
- 6. 以上安装Nginx的FastDFS扩展模块注意事项
- 7. FastDFS扩展模块执行流程
- 3.3 FastDFS的Nginx访问配置
- 1. 修改mod_fastdfs.conf配置文件
- 2. 在/opt/fastdfs/目录下创建nginx_mod目录
- 3. 配置Nginx的配置文件
- 3.4 FastDFS的Nginx访问启动与测试
- 1. 启动带有Fastdfs模块的Nginx
- 2. 重启或启动FastDFS服务进程
- 3. 上传一个文件进行测试验证
- 4. 在浏览器访问上传的文件
- 5. 扩展
- 4、FastDFS分布式文件系统Java客户端
- 4.1 FastDFS文件系统的Java客户端
- 1. 下载官方的源代码
- 2. 解压
- 3. 采用maven命令编译成jar安装到本地maven库
- 4. 在Java程序中使用它提供的API来访问FastDFS文件系统
- 4.2 FastDFS文件上传功能实现
- 4.2.1 **需求**
- 4.2.2 实现步骤
- 4.3 FastDFS文件上传功能封装
- 4.3.1 需求
- 4.3.2 实现步骤
- 5、FastDFS在web项目中的应用
- 1. 数据库环境搭建
- ⒉ 开发环境搭建
- 6、FastDFS分布式文件系统集群
- 6.1 架构图
- 6.2 环境搭建步骤
- 1. 安装6个迷你版的Linux
- 2. 在Xshell中创建6个连接,分别连向不同的Linux
- 3. 为迷你版的Linux安装常用工具库
- 4. 按照课件上安装FastDFS的步骤在6个服务器节点安装FastDFS
- 5. 配置两个tracker server服务器
- 6. 配置四个storage server服务器
- 7. 部署Http访问FastDFS上的文件
1、分布式文件系统
1.1 FastDFS简介
分布式文件系统 (Distributed File System) 是一个软件/软件服务器,这个软件可以用来管理文件。但这个软件所管理的文件通常不是在一个服务器节点上,而是在多个服务器节点上,这些服务器节点通过网络相连构成一个庞大的文件存储服务器集群,这些服务器都用于存储文件资源,通过分布式文件系统来管理这些服务器上的文件。
FastDFS 是一个开源的高性能分布式文件系统(DFS)。 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡。主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。
FastDFS是一个开源的轻量级分布式文件系统,为互联网应用量身定做,简单、灵活、高效,采用C语言开发,由阿里巴巴开发并开源。
FastDFS对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载、文件删除)等,解决了大容量文件存储的问题,特别适合以文件为载体的在线服务,如相册网站、文档网站、图片网站、视频网站等等。
FastDFS充分考虑了冗余备份、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
FastDFS 系统有三个角色:跟踪服务器(Tracker Server)、存储服务器(Storage Server)和客户端(Client)。
Tracker Server
:跟踪服务器,主要做调度工作,起到均衡的作用;负责管理所有的 storage server和 group,每个 storage 在启动后会连接 Tracker,告知自己所属 group 等信息,并保持周期性心跳。Storage Server
:存储服务器,主要提供容量和备份服务;以 group 为单位,每个 group 内可以有多台 storage server,数据互为备份。Client
:客户端,上传下载数据的服务器,也就是我们自己的项目所部署在的服务器。
- 常见的分布式文件系统有:FastDFS、GFS、HDFS、Lustre 、Ceph 、GridFS 、mogileFS、TFS等。
1.2 FastDFS整体架构
FastDFS代码托管在github上:https://github.com/happyfish100/fastdfs
FastDFS文件系统由两大部分构成,一个是客户端,一个是服务端
客户端通常指我们的程序,比如我们的Java程序去连接FastDFS、操作FastDFS,那我们的Java程序就是一个客户端,FastDFS提供专有API访问,目前提供了C、Java和PHP几种编程语言的API,用来访问FastDFS文件系统。
服务端由两个部分构成:一个是跟踪器(tracker),一个是存储节点(storage)
- 跟踪器(tracker)主要做调度工作,在内存中记录集群中存储节点storage的状态信息,是前端Client和后端存储节点storage的枢纽。因为相关信息全部在内存中,Tracker server的性能非常高,一个较大的集群(比如上百个group)中有3台就足够了。
- 存储节点(storage)用于存储文件,包括文件和文件属性(meta data)都保存到存储服务器磁盘上,完成文件管理的所有功能:文件存储、文件同步和提供文件访问等。
1.3 FastDFS的存储策略
为了支持大容量,存储节点(服务器)采用了分卷(或分组)的组织方式。存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的,所有卷的文件容量累加就是整个存储系统中的文件容量。一个卷可以由一台或多台存储服务器组成,一个卷下的存储服务器中的文件都是相同的,卷中的多台存储服务器起到了冗余备份和负载均衡的作用。
在卷中增加服务器时,同步已有的文件由系统自动完成,同步完成后,系统自动将新增服务器切换到线上提供服务。当存储空间不足或即将耗尽时,可以动态添加卷。只需要增加一台或多台服务器,并将它们配置为一个新的卷,这样就扩大了存储系统的容量。
1.4 FastDFS的上传过程
FastDFS向使用者提供基本文件访问接口,比如upload、download、append、delete等,以客户端库的方式提供给用户使用。
Storage Server会定期的向Tracker Server发送自己的存储信息。当Tracker Server Cluster中的Tracker Server不止一个时,各个Tracker之间的关系是对等的,所以客户端上传时可以选择任意一个Tracker。
当Tracker收到客户端上传文件的请求时,会为该文件分配一个可以存储文件的group,当选定了group后就要决定给客户端分配group中的哪一个storage server。当分配好storage server后,客户端向storage发送写文件请求,storage将会为文件分配一个数据存储目录。然后为文件分配一个fileid,最后根据以上的信息生成文件名存储文件。
1.5 FastDFS的文件同步
写文件时,客户端将文件写至group内一个storage server即认为写文件成功,storage server写完文件后,会由后台线程将文件同步至同group内其他的storage server。
每个storage写文件后,同时会写一份binlog,binlog里不包含文件数据,只包含文件名等元信息,这份binlog用于后台同步,storage会记录向group内其他storage同步的进度,以便重启后能接上次的进度继续同步;进度以时间戳的方式进行记录,所以最好能保证集群内所有server的时钟保持同步。
storage的同步进度会作为元数据的一部分汇报到tracker上,tracke在选择读storage的时候会以同步进度作为参考。
1.6 FastDFS的文件下载
- 客户端uploadfile成功后,会拿到一个storage生成的文件名,接下来客户端根据这个文件名即可访问到该文件。
- 跟upload file一样,在downloadfile时客户端可以选择任意tracker server。tracker发送download请求给某个tracker,必须带上文件名信息,tracke从文件名中解析出文件的group、大小、创建时间等信息,然后为该请求选择一个storage用来服务读请求。
2、FastDFS环境搭建
2.1 FastDFS安装
2.1.1 安装前的准备
(1) 检查Linux上是否安装了 gcc、libevent、libevent-devel
yum list installed | grep gccyum list installed | grep libeventyum list installed | grep libevent-devel
(2) 如果没有安装,则需进行安装
yum install gcc libevent libevent-devel –y
2.1.2 安装 libfastcommon 库
- libfastcommon 库是 FastDFS 文件系统运行需要的公共 C 语言函数库
注意
:目前最新版本的v1.0.39和最新版的FastDFS5.11不兼容,所有我们这里使用的版本是v1.0.36 下载地址:https://github.com/happyfish100
(1) 将下载好的libfastcommon文件上传到Linux(/home/)
(2) 解压下载下来的tar.gz压缩包到当前目录
tar -zxvf libfastcommon-1.0.36.tar.gz
(3) 切换到解压后的libfastcommon目录
cd libfastcommon-1.0.36
(4) 执行make脚本进行编译
./make.sh
注意
: make编译的时候如果报错,需解决错误后再次进行make,通常发生错误是由于Linux缺少某些依赖库导致,根据错误提示解决错误
(5) 执行make install进行安装
./make.sh install
2.1.3 安装FastDFS
FastDFS没有Windows版本,不能在Windows下使用。
FastDFS需要安装部署在Linux环境下,我们这里使用的是fastdfs-5.11版本(201901)
下载地址:https://github.com/happyfish100/fastdfs/archive/V5.11.tar.gz
(1) 将下载好的FastDFS文件上传到Linux(/home/)
(2) 解压下载下来的tar.gz压缩包到当前目录
tar -zxvf fastdfs-5.11.tar.gz
(3) 切换到解压后FastDFS的目录
cd fastdfs-5.11
(4) 执行make脚本进行编译
./make.sh
(5) 执行make install进行安装
./make.sh install
所有编译出来的文件存放在/usr/bin目录下
所有配置文件存放在/etc/fdfs目录下
(6) 查看安装后的效果
A、 查看FastDFS相关的可执行程序
ll /usr/bin/fdfs*
- /usr/bin是Linux的环境变量,可通过echo $PATH查看
B、 查看FastDFS的配置文件
ll /etc/fdfs/
(7) 另外注意需要把解压后的fastdfs-5.11/conf目录下的两个文件拷贝到/etc/fdfs/ ,否则后续会有很多奇怪问题不好解决
cp http.conf /etc/fdfs/cp mime.types /etc/fdfs/
2.2 FastDFS配置文件详解
1. 去掉/etc/fdfs/目录下FastDFS配置文件的后缀名
2. 修改tracker.conf文件
- 默认指向的FastDFS作者余庆的目录,因为在我们的机器上不存在,所有手动改一下
base_path=/opt/fastdfs/tracker #配置tracker存储数据的目录
3. 修改storage.conf文件
base_path=/opt/fastdfs/storage #storage存储数据目录store_path0=/opt/fastdfs/storage/files #真正存放文件的目录tracker_server=192.168.235.128:22122 #注册当前存储节点的跟踪器地址
4. 在Linux服务器上创建上面指定的目录
/opt/fastdfs/tracker/opt/fastdfs/storage/opt/fastdfs/storage/files
5. 然后启动FastDFS
2.3 FastDFS启动
FastDFS服务启动需要启动两个脚本:
1. 启动FastDFS的tracker服务
在任意目录下执行:fdfs_trackerd /etc/fdfs/tracker.conf
2. 启动FastDFS的storage服务
在任意目录下执行:fdfs_storaged /etc/fdfs/storage.conf
3. 查看启动进程
有启动的执行命令即为启动成功
4. 查看storage是否已经注册到了tracker下
fdfs_monitor /etc/fdfs/storage.conf
5. 首次启动storage后,会在配置的路径下创建存储文件的目录
2.4 FastDFS重启与FastDFS关闭
2.4.1 FastDFS重启
- 重启tracker
fdfs_trackerd /etc/fdfs/tracker.conf restart
- 重启storage
fdfs_storaged /etc/fdfs/storage.conf restart
2.4.2 FastDFS关闭
- 关闭tracker执行命令
在任意目录下执行:fdfs_trackerd /etc/fdfs/tracker.conf stop
- 关闭storage执行命令
在任意目录下执行:fdfs_storaged /etc/fdfs/storage.conf stop
或者kill关闭fastdfs,但不建议在线上使用kill -9
强制关闭,因为可能会导致文件信息不同步
问题。
2.5 FastDFS测试
FastDFS安装完成之后,可以使用fdfs_test
脚本测试文件上传。
测试之前,需要修改client.conf配置文件,修改两个配置
base_path=/opt/fastdfs/clienttracker_server=192.168.179.128:22122
在/opt/fastdfs/
目录下创建client
2.5.1 测试文件上传
- 准备需要上传的文件
- 执行上传命令fdfs_test /etc/fdfs/client.conf upload /root/aa.txt
- 切换到存储目录查看文件上传情况
FastDFS生成的文件目录结构及名称示例
2.5.2 测试文件删除
fdfs_delete_file /etc/fdfs/client.conf group1/要删除的文件路径
注意
● 没有搭建集群默认只有一个组group1
● 后缀名包含-m的为属性文件(meta)
● 在Linux中并没有磁盘一说,是虚拟的
3、分布式文件系统FastDFS的HTTP访问
概述
在文件上传的时候,上传成功的信息中有提示我们可以通过某个路径去访问上传的文件,但是我们直接访问这个路径,却不可以,那么已经上传到FastDFS文件系统中的文件,我们如何在浏览器中访问呢?
FastDFS提供了一个Nginx扩展模块,利用该模块,我们可以通过Nginx访问已经上传到FastDFS上的文件
3.1 前期准备工作
将Fastdfs的Nginx扩展模块源代码上传到Linux上
解压下载下来的fastdfs-nginx-module-master.zip 文件
unzip fastdfs-nginx-module-master.zip
3.2 安装Nginx并且添加fastDFS模块
因为这个模块必须在Nginx的安装的过程中才能添加,所有我们需要重新安装一个nginx,为了和原来已安装的Nginx进行区分,我们把新安装的Nginx取名为nginx_fdfs
1. 将Nginx的tar包上传到Linux上
2. 解压上传的Nginx文件
3. 切换至解压后的Nginx主目录,执行配置操作
cd nginx-1.14.2./configure --prefix=/usr/local/nginx_fdfs --add-module=/home/soft/fastdfs-nginx-module-master/src
• prefix是指定nginx安装路径
• add-module指定fastDFS的nginx模块的源代码路径
# 常见报错问题
①/home/dfs/fastdfs-nginx-module-master/src/common.c:351:32: error: request for member ‘path’ in something not a structure or uniong_fdfs_store_paths.paths[i].path);解决方案:
原因:软件不匹配!# wget https://sourceforge.net/projects/fastdfs/files/FastDFS%20Nginx%20Module%20Source%20Code/fastdfs-nginx-module_v1.16.tar.gz
# tar -zxvf fastdfs-nginx-module_v1.16.tar.gz ②/home/dfs/fastdfs-nginx-module/src/common.c:21:25: fatal error: fdfs_define.h: No such file or directory#include "fdfs_define.h"解决方案:
原因:编译安装nginx的fastdfs插件的头文件没有找到,由于编译nginx时候系统会到/usr/local /include编译安装fastdfs-nginx-module时则默认保存在了/usr/include目录。
修复:ln -s /usr/include/fast* /usr/local/include/③ fatal error: common_define.h: No such file or directory
解决方案:
原因:在安装FastDFS的时候,其中的函数声明、宏定义、函数原型被指到了 “ /usr/include/fastdfs /usr/include/fastcommon ” 目录下vi /home/dfs/fastdfs-nginx-module/src/configngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"》》》CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
4. 执行命令进行编译
make
5. 执行命令进行安装
make install
6. 以上安装Nginx的FastDFS扩展模块注意事项
我们知道,Nginx的安装需要Linux安装相关的几个库,否则编译会出现错误,这几个库分别是:
• gcc编译器是否安装
检查是否安装:yum list installed | grep gcc
执行安装:yum install gcc -y
• openssl库是否安装
检查是否安装:yum list installed | grep openssl
执行安装:yum install openssl openssl-devel -y
• pcre库是否安装
检查是否安装:yum list installed | grep pcre
执行安装:yum install pcre pcre-devel -y
• zlib库是否安装
检查是否安装:yum list installed | grep zlib
执行安装:yum install zlib zlib-devel -y
yum install gcc openssl openssl-devel pcre pcre-devel zlib zlib-devel –y
7. FastDFS扩展模块执行流程
3.3 FastDFS的Nginx访问配置
将/home/soft/fastdfs-nginx-module-master/src(自己实际存放Nginx扩展模块的目录)目录下的mod_fastdfs.conf文件拷贝到 /etc/fdfs/目录下,这样才能正常启动Nginx
cp /home/soft/fastdfs-nginx-module-master/src/mod_fastdfs.conf /etc/fdfs/
1. 修改mod_fastdfs.conf配置文件
base_path=/opt/fastdfs/nginx_modtracker_server=192.168.235.128:22122url_have_group_name = truestore_path0=/opt/fastdfs/storage/files
2. 在/opt/fastdfs/目录下创建nginx_mod目录
3. 配置Nginx的配置文件
#拦截请求路径中包含 /group[1-9]/M0[0-9] 的请求,用 fastdfs的Nginx 模块进行转发
location ~ /group[1-9]/M0[0-9] { ngx_fastdfs_module;
}
ngx_fastdfs_module; #这个指令不是Nginx本身提供的,是扩展模块提供的,根据这个指令找到FastDFS提供的Nginx模块配置文件,然后找到Tracker,最终找到Stroager。
3.4 FastDFS的Nginx访问启动与测试
1. 启动带有Fastdfs模块的Nginx
2. 重启或启动FastDFS服务进程
fdfs_trackerd /etc/fdfs/tracker.conf restartfdfs_storaged /etc/fdfs/storage.conf restart
3. 上传一个文件进行测试验证
fdfs_test /etc/fdfs/client.conf upload /root/aa.txt
4. 在浏览器访问上传的文件
当遇到400错误,检查配置/etc/fdfs/mod_fastdfs.conf
url_have_group_name=true
该配置表示访问路径中是否需要带有group1,改为true表示路径中需要有group1
5. 扩展
模拟大型网站用户头像的处理方式,上传一张图片,然后自己写一个html页面,src指向上传的图片。
4、FastDFS分布式文件系统Java客户端
在实际项目开发中,FastDFS提供的主要功能
● upload:上传文件
● download:下载文件
● delete:删除文件
4.1 FastDFS文件系统的Java客户端
FastDFS文件系统Java客户端是指采用Java语言编写的一套程序,专门用来访问fastDFS文件系统,其实就是一个jar包。
注意:大家如果能连上 mvnrepository上搜索到的用友云提供的fastdfs-client,那大家就下载那个jar包使用,如果连不上,这个jar包需要我们自己来打。
1. 下载官方的源代码
从https://codeload.github.com/happyfish100/fastdfs-client-java/zip/master上下载FastDFS源代码到本地
2. 解压
3. 采用maven命令编译成jar安装到本地maven库
mvn clean install
4. 在Java程序中使用它提供的API来访问FastDFS文件系统
4.2 FastDFS文件上传功能实现
4.2.1 需求
使用Java客户端,编程操作fastDFS分布式文件系统,上传本地文件到FastDFS服务器上。
4.2.2 实现步骤
- 使用IDEA创建普通的maven项目,不需要使用
- 在pom.xml文件中添加我们打包好的FastDFS本地仓库的jar包(FastDFS的java客户端依赖)
<!--加入FastDFS的java客户端依赖-->
<dependencies><dependency><groupId>org.csource</groupId><artifactId>fastdfs-client-java</artifactId><version>1.27-SNAPSHOT</version></dependency>
</dependencies>
- 拷贝源代码包中的fdfs_client.conf文件到resources目录下,在里面主要配置tracker地址
tracker_server = 192.168.235.128:22122
- 编写代码,进行上传测试
在com.bjpowernode.fastdfs包下创建FastDFS类,在其中编写上传代码
package com.bjpowernode.fastdfs;
import org.csource.common.MyException;
import org.csource.fastdfs.*;
import java.io.IOException;
public class FastDFS {public static void main(String[] args) {fileUpload();}//上传文件的方法public static void fileUpload(){TrackerServer trackerServer = null;StorageServer storageServer = null;try {//1.加载配置文件,默认去classpath下加载ClientGlobal.init("fdfs_client.conf");//2.创建TrackerClient对象TrackerClient trackerClient = new TrackerClient();//3.创建TrackerServer对象trackerServer = trackerClient.getConnection();//4.创建StorageServler对象storageServer = trackerClient.getStoreStorage(trackerServer);//5.创建StorageClient对象,这个对象完成对文件的操作StorageClient storageClient = new StorageClient(trackerServer,storageServer);//6.上传文件 第一个参数:本地文件路径 第二个参数:上传文件的后缀 第三个参数:文件信息String [] uploadArray = storageClient.upload_file("D:/aa.txt","txt",null);for (String str:uploadArray) {System.out.println(str);}} catch (IOException e) {e.printStackTrace();} catch (MyException e) {e.printStackTrace();} finally {if(storageServer != null){try {storageServer.close();} catch (IOException e) {e.printStackTrace();}}if(trackerServer != null){try {trackerServer.close();} catch (IOException e) {e.printStackTrace();}}}}
}
- 运行程序,在Linux上,FastDFS存储目录下查看上传文件内容
4.3 FastDFS文件上传功能封装
4.3.1 需求
因为使用FastDFS进行文件操作代码大多都是通用的,所以我们这里在FastDFS类中将通用的功能进行封装,并提供上传、下载、删除文件的方法。
注意:这里只是简单的封装,如果多线程会有问题
4.3.2 实现步骤
- 抽取获取StorageClient的方法
public static StorageClient getStorageClient() throws IOException, MyException {//1.加载配置文件,默认去classpath下加载ClientGlobal.init("fdfs_client.conf");//2.创建TrackerClient对象TrackerClient trackerClient = new TrackerClient();//3.创建TrackerServer对象trackerServer = trackerClient.getConnection();//4.创建StorageServler对象storageServer = trackerClient.getStoreStorage(trackerServer);//5.创建StorageClient对象,这个对象完成对文件的操作StorageClient storageClient = new StorageClient(trackerServer,storageServer);return storageClient;
}
- 定义两个全局变量
private static TrackerServer trackerServer = null;
private static StorageServer storageServer = null;
- 抽取关闭资源的方法
public static void closeFastDFS() {if (storageServer != null) {try {storageServer.close();} catch (IOException e) {e.printStackTrace();}}if (trackerServer != null) {try {trackerServer.close();} catch (IOException e) {e.printStackTrace();}}
}
- 改造文件上传的方法
public static void fileUpload(){try {//1. 获取StorageClient对象StorageClient storageClient = getStorageClient();//2.上传文件 第一个参数:本地文件路径 第二个参数:上传文件的后缀 第三个参数:文件信息String [] uploadArray = storageClient.upload_file("D:/aa.txt","txt",null);for (String str:uploadArray) {System.out.println(str);}} catch (IOException e) {e.printStackTrace();} catch (MyException e) {e.printStackTrace();} finally {closeFastDFS();}
}
- 下载文件的方法
/下载文件的方法
public static void fileDownload(){try {//1. 获取StorageClient对象StorageClient storageClient = getStorageClient();//2.下载文件 返回0表示成功,其它均表示失败int num = storageClient.download_file("group1","M00/00/00/wKjrgFxOqueAAPWKAAAAKAM14xY563.txt","E:/bb.txt");System.out.println(num);} catch (IOException e) {e.printStackTrace();} catch (MyException e) {e.printStackTrace();} finally {closeFastDFS();}
}
- 删除文件的方法
/删除文件的方法
public static void fileDelete(){try {//1. 获取StorageClient对象StorageClient storageClient = getStorageClient();//2.删除文件 返回0表示成功,其它均表示失败int num = storageClient.delete_file("group1","M00/00/00/wKjrgFxOqueAAPWKAAAAKAM14xY563.txt");System.out.println(num);} catch (IOException e) {e.printStackTrace();} catch (MyException e) {e.printStackTrace();} finally {closeFastDFS();}
}
- 主方法调用不同的方法进行测试
5、FastDFS在web项目中的应用
需求
对P2P项目合同进行管理,在WEB项目中实现对文件的上传下载和删除操作。
名词解释
● 有一些债权:投资人有该债务的权利
注:通常隐含的意思就是:一笔借款常被称为一个债权。
● 一个债权会有一个合同
● 合同是pdf文件
● 债权是债务的对应词,但是在P2P项目中,我们管理的债权,以及合同一般指的是借款人的信息,所以在我们下面创建的creditor_info表中存的是借款人信息
目标
● 实现对pdf文件上传、下载、删除
● 熟练一下Springboot+thymeleaf
案例实现步骤
1. 数据库环境搭建
① 创建数据库fastdfs
② 在该库下创建creditor_info表
CREATE TABLE `creditor_info` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`realName` varchar(35) DEFAULT NULL COMMENT '债权借款人姓名',
`idCard` varchar(18) DEFAULT NULL COMMENT '债权借款人身份证',
`address` varchar(150) DEFAULT NULL COMMENT '债权借款人地址',
`sex` int(1) DEFAULT NULL COMMENT '1男2女',
`phone` varchar(11) DEFAULT NULL COMMENT '债权借款人电话',
`money` decimal(10,2) DEFAULT NULL COMMENT '债权借款人借款金额',
`groupName` varchar(10) DEFAULT NULL COMMENT '债权合同所在组',
`remoteFilePath` varchar(150) DEFAULT NULL COMMENT '债权合同所在路径',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
⒉ 开发环境搭建
① 创建SpringBoot项目10-fastdfs-web,添加Web和Thymeleaf依赖
② 在pom.xml文件中添加Mybatis依赖及MySQL依赖
<!-- 加载mybatis整合springboot -->
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><!--在springboot的父工程中没有指定版本,我们需要手动指定--><version>1.3.2</version>
</dependency>
<!-- MySQL的jdbc驱动包 -->
<dependency><groupId>mysql</groupId><!--在springboot的父工程中指定了版本,我们就不需要手动指定了--><artifactId>mysql-connector-java</artifactId>
</dependency>
③ 在pom.xml文件中添加resources,指定编译的位置
<resources><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes></resource><resource><directory>src/main/resources</directory><includes><include>**/*.*</include></includes></resource><!--如果存在jsp,需要指定jsp文件编译的位置-->
</resources>
④ 在SpringBoot主配置文件application.properties中添加数据库配置信息
#数据库的连接配置信息
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.235.128:3306/fastdfs?useUnicode=true&characterEncoding=utf8&useSSL=false
⑤ 使用Mybatis反向工程,生成实体类及mapper映射(参照SpringBoot附录教程)
A、在pom.xml文件中添加反向工程插件
<!--mybatis代码自动生成插件-->
<plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.7</version><configuration><!--配置文件的位置--><configurationFile>GeneratorMapper.xml</configurationFile><verbose>true</verbose><overwrite>true</overwrite></configuration>
</plugin>
B、 从03-springboot-web中复制GeneratorMapper.xml到当前项目下
C、 修改GeneratorMapper.xml配置文件内容
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration><!-- 指定连接数据库的JDBC驱动包所在位置,指定到你本机的完整路径 --><classPathEntry location="D:/repository/mysql/mysql-connector-java/8.0.13/mysql-connector-java-8.0.13.jar"/><!-- 配置table表信息内容体,targetRuntime指定采用MyBatis3的版本 --><context id="tables" targetRuntime="MyBatis3"><!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 --><commentGenerator><property name="suppressAllComments" value="true" /></commentGenerator><!-- 配置数据库连接信息 注意:使用高版本的驱动 url后面应该加属性nullCatalogMeansCurrent=true,否则生成有问题 --><jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"connectionURL="jdbc:mysql://192.168.235.128:3306/fastdfs?nullCatalogMeansCurrent=true"userId="root"password="123456"></jdbcConnection><!-- 生成model类,targetPackage指定model类的包名, targetProject指定生成的model放在eclipse的哪个工程下面--><javaModelGenerator targetPackage="com.bjpowernode.fastdfs.model" targetProject="src/main/java"><property name="enableSubPackages" value="false" /><property name="trimStrings" value="false" /></javaModelGenerator><!-- 生成MyBatis的Mapper.xml文件,targetPackage指定mapper.xml文件的包名, targetProject指定生成的mapper.xml放在eclipse的哪个工程下面 --><sqlMapGenerator targetPackage="com.bjpowernode.fastdfs.mapper" targetProject="src/main/java"><property name="enableSubPackages" value="false" /></sqlMapGenerator><!-- 生成MyBatis的Mapper接口类文件,targetPackage指定Mapper接口类的包名, targetProject指定生成的Mapper接口放在eclipse的哪个工程下面 --><javaClientGenerator type="XMLMAPPER" targetPackage="com.bjpowernode.fastdfs.mapper" targetProject="src/main/java"><property name="enableSubPackages" value="false" /></javaClientGenerator><!-- 数据库表名及对应的Java模型类名 --><table tableName="creditor_info"domainObjectName="CreditorInfo"enableCountByExample="false"enableUpdateByExample="false"enableDeleteByExample="false"enableSelectByExample="false"selectByExampleQueryId="false"/></context>
</generatorConfiguration>
D、双击生成
⑥ 创建相关的包和类
在com.bjpowernode.fast包下创建controller ,service 包,及其子包impl
创建CreditorInfoController类
创建CreditorInfoService接口
创建CreditorInfoServiceImpl实现类
3. 功能实现-展示所有债权信息
① 在CreditorInfoController类中创建index方法,将CreditorInfoService注入到controller中
@Controller
public class CreditorInfoController {@Autowiredprivate CreditorInfoService creditorInfoService;@GetMapping("/fastdfs/index")public String index(Model model){List<CreditorInfo> creditorInfoList = creditorInfoService.getAllCreditorInfo();model.addAttribute("creditorInfoList",creditorInfoList);//模板页面,不是jspreturn "index";}
}
② 在CreditorInfoService中提供getAllCreditorInfo方法
public interface CreditorInfoService {/*** 获取所有债权信息* @return*/List<CreditorInfo> getAllCreditorInfo();
}
③ 在CreditorInfoServiceImpl中对getAllCreditorInfo方法进行实现
@Service
public class CreditorInfoServiceImpl implements CreditorInfoService {@Autowiredprivate CreditorInfoMapper creditorInfoMapper;@Overridepublic List<CreditorInfo> getAllCreditorInfo() {return creditorInfoMapper.selectAllCreditorInfo();}
}
④ 因为是SpringBoot项目,所以需要在Mapper接口上加一个Mapper注解
@Mapper
public interface CreditorInfoMapper {}
⑤ 在CreditorInfoMapper类中添加selectAllCreditorInfo方法
List<CreditorInfo> selectAllCreditorInfo();
⑥ 在IDEA中安装free Mybatis插件
该插件可以通过点击Mapper接口中的方法,进入到.xml文件
A、 SettingsàpluginsàBrowse repositories
B、 在插件库中搜索,free mybatis安装
C、 插件安装完毕,需要重启IDEA
⑦ 在CreditorInfoMapper.xml文件中添加SQL语句
<select id="selectAllCreditorInfo" resultMap="BaseResultMap">select<include refid="Base_Column_List"/>from creditor_info
</select>
⑧ 展示页面的设计
A、 在项目的templates目录下创建index.html
B、 百度搜索bootstrap表格,挑选自己喜欢风格的表格,将代码拷贝到index.html中
我这里使用的是http://www.bjpowernode.com/try/try.php?
filename=bootstrap3-table-striped表格进行改写
C、 在html标签上加上Thymeleaf的命名空间
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
D、 修改index.html内容
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="utf-8"><title>债权合同管理</title><link rel="stylesheet" th:href="@{/css/bootstrap-3.3.7.min.css}"><script th:src="@{/js/jquery-2.1.1.min.js}"></script><script th:src="@{/js/bootstrap-3.3.7.min.js}"></script>
</head>
<body>
<table class="table table-striped"><caption>债权合同信息列表</caption><thead><tr><th>序号</th><th>债权借款人姓名</th><th>债权借款人身份证</th><th>债权借款人住址</th><th>债权借款人手机号</th><th>债权借款人性别</th><th>债权借款人借款金额</th></tr></thead><tbody><tr th:each="creditorInfo:${creditorInfoList}"><td th:text="${creditorInfoStat.count}"></td><td th:text="${creditorInfo.realname}"></td><td th:text="${creditorInfo.idcard}"></td><td th:text="${creditorInfo.address}"></td><td th:text="${creditorInfo.phone}"></td><td th:text="${creditorInfo.sex == 1 ?'男':'女'}"></td><td th:text="${creditorInfo.money}"></td></tr></tbody>
</table>
</body>
</html>
注意:我们从网络上拷贝过来的内容css,js等是联网获取的,我们这里可以从04-FastDFS\resources获取,并放在项目的static的相关目录下,在页面上引用
⑨ 向数据库中加几条数据
⑩ 启动项目,访问http://localhost:8080/fastdfs/index 查看效果
⑪ 调整页面样式
<body style="margin: 50px">
- 功能实现-为某一个债权合同上传文件
① 在index.html中添加操作列
<th>合同管理</th><td><!--为哪个合同上传,需要将合同的id传递过去--><a th:href="@{'/fastdfs/toUpload?id=' + ${creditorInfo.id}}">上传</a>下载删除
</td>
② 在CreditorController中添加跳转到上传页面的方法
@GetMapping("/fastdfs/toUpload")
public String toUpload(Model model, @RequestParam("id") Integer id){model.addAttribute("id",id);return "upload";
}
③ 在templates下创建upload.html页面
在网上搜索bootstrap表单,并对其内容进行修改,我这里使用的是
http://www.bjpowernode.com/try/try2.php?filename=bootstrap3-form-inline
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="utf-8"><title>债权合同上传</title><link rel="stylesheet" th:href="@{/css/bootstrap-3.3.7.min.css}"><script th:src="@{/js/jquery-2.1.1.min.js}"></script><script th:src="@{/js/bootstrap-3.3.7.min.js}"></script>
</head>
<body><form th:action="@{/fastdfs/upload}" class="form-inline" role="form" method="post" enctype="multipart/form-data"><div class="form-group"><label class="sr-only" for="fileName">文件输入</label><input type="file" id="fileName" name="fileName"></div><input type="hidden" name="id" th:value="${id}"><button type="submit" class="btn btn-default">提交</button></form>
</body>
</html>
注意
:
● 文件上传必须是post请求
● enctype必须为multipart/form-data
● 合同的id通过隐藏域传递
④ 在pom.xml文件中加入FastDFS客户端的jar包依赖
<!--加入FastDFS的java客户端依赖-->
<dependency><groupId>org.csource</groupId><artifactId>fastdfs-client-java</artifactId><version>1.27-SNAPSHOT</version>
</dependency>
⑤ 将FastDFS客户端的配置文件fast_client.conf拷贝到resources目录下
⑥ 将原来我们封装的FastDFS类拷贝到fastdfs包下,修改其中的file_upload方法,定义一些参数
去掉主方法,新的fileUpload写法如下:
/上传文件的方法
public static String[] fileUpload(byte[] fileBytes,String fileExt){String [] uploadArray = null;try {//1. 获取StorageClient对象StorageClient storageClient = getStorageClient();//2.上传文件 第一个参数:本地文件路径 第二个参数:上传文件的后缀 第三个参数:文件信息uploadArray = storageClient.upload_file(fileBytes,fileExt,null);} catch (IOException e) {e.printStackTrace();} catch (MyException e) {e.printStackTrace();} finally {closeFastDFS();}return uploadArray;
}
⑦ 在CreditorController中添加处理上传文件的方法
@PostMapping("/fastdfs/upload")
public @ResponseBody String upload(@RequestParam("id") Integer id, @RequestParam("fileName") MultipartFile file){//原来文件上传是将文件写到本地或者远程服务器的某个目录下//现在的文件上传是将文件上传到fastdfs文件服务器上//1表示上传失败 0表示成功int result = 1;//abc.txt -->txtString fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().indexOf(".") + 1);try {String[] uploadArray = FastDFS.fileUpload(file.getBytes(),fileExt);if(uploadArray != null && uploadArray.length ==2){//文件上传到fastDFS成功 ,将合同文件路径更新到债权记录中CreditorInfo creditorInfo = new CreditorInfo();creditorInfo.setId(id);creditorInfo.setGroupname(uploadArray[0]);creditorInfo.setRemotefilepath(uploadArray[1]);int updateRow = creditorService.updateCreditorInfo(creditorInfo);//数据库更新成功if(updateRow > 0){result = 0;}}} catch (IOException e) {e.printStackTrace();}return "<script>window.parent.uploadOK('"+result+"')</script>";
}
⑧ 在CreditorInfoService中添加updateCreditorInfo方法
/*** 更新债权信息* @param creditorInfo* @return*/
int updateCreditorInfo(CreditorInfo creditorInfo);
⑨ 在CreditorInfoServiceImpl中添加updateCreditorInfo方法实现
@Override
public int updateCreditorInfo(CreditorInfo creditorInfo) {return creditorInfoMapper.updateByPrimaryKeySelective(creditorInfo);
}
⑩ 在upload.html做一个类似ajax的页面不刷新效果
● 在upload.html页面中加一个iframe
● upload.html页面中的form中的target设置为iframe的name
● 在iframe的父页面中,写一个函数,处理上传结果
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="utf-8"><title>债权合同上传</title><link rel="stylesheet" th:href="@{/css/bootstrap-3.3.7.min.css}"><script th:src="@{/js/jquery-2.1.1.min.js}"></script><script th:src="@{/js/bootstrap-3.3.7.min.js}"></script>
</head>
<body><form th:action="@{/fastdfs/upload}" class="form-inline" role="form" method="post" target="uploadFrame" enctype="multipart/form-data"><div class="form-group"><label class="sr-only" for="fileName">文件输入</label><input type="file" id="fileName" name="fileName"></div><input type="hidden" id="id" name="id" th:value="${id}"><button type="submit" class="btn btn-default">提交</button></form><iframe name="uploadFrame" style="display: none;"></iframe><script type="text/javascript" th:inline="javascript">function uploadOK(result){if(result == 0){//文件上传成功alert("文件上传成功");var contextPath = [[${#request.getContextPath()}]];window.location.href = contextPath + "/fastdfs/index";}else{alert("文件上传失败");}}</script>
</body>
</html>
⑪ 如果上传文件超出了1M,需要在application.properties中配置SpringBoot上传文件的最大限制
#SpringBoot上传文件的最大限制
spring.servlet.multipart.max-file-size=10MB
注意
:如果提示找不到tracker_server,看看是否编译到target中
- 功能实现-下载某一个债权合同
① 修改index.html页面,下载加连接,并做判断
<td><span th:if="${creditorInfo.getGroupname() ne null && creditorInfo.remotefilepath ne null}"><a th:href="@{'/fastdfs/download?id=' + ${creditorInfo.id}}">下载</a>删除</span><span th:unless="${creditorInfo.getGroupname() ne null && creditorInfo.remotefilepath ne null}"><!--为哪个合同上传,需要将合同的id传递过去--><a th:href="@{'/fastdfs/toUpload?id=' + ${creditorInfo.id}}">上传</a></span>
</td>
② 在CreditorController中,完成下载的请求
● ResponseEntity通常用于返回文件流
● @ResponseBody可以直接返回Json结果,
● @ResponseEntity不仅可以返回json结果,还可以定义返回的HttpHeaders和HttpStatus
● ResponseEntity的优先级高于@ResponseBody。在不是ResponseEntity的情况下才去检查有没有@ResponseBody注解。如果响应类型是ResponseEntity可以不写@ResponseBody注解,写了也没有关系。
@GetMapping("/fastdfs/download")
public ResponseEntity<byte[]> download(@RequestParam("id") Integer id){//根据债权id获取 债权对象CreditorInfo creditorInfo = creditorInfoService.getCreditorInfoById(id);String extName = creditorInfo.getRemotefilepath().substring(creditorInfo.getRemotefilepath().indexOf("."));byte [] fileBytes = FastDFS.fileDownload(creditorInfo.getGroupname(),creditorInfo.getRemotefilepath());HttpHeaders httpHeaders = new HttpHeaders();httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);//流类型httpHeaders.setContentDispositionFormData("attachment",System.currentTimeMillis() + extName);ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(fileBytes,httpHeaders, HttpStatus.OK);return responseEntity;
}
③ 在CreditorService接口中添加getCreditorInfoById的方法
/*** 根据合同id获取债权信息* @param id* @return*/
CreditorInfo getCreditorInfoById(Integer id);
④ 在CreditorServiceImpl中添加getCreditorInfoById方法的实现
@Override
public CreditorInfo getCreditorInfoById(Integer id) {return creditorInfoMapper.selectByPrimaryKey(id);
}
⑤ 修改FastDFS类中fileDown方法的实现,传递参数
//下载文件的方法
public static byte[] fileDownload(String group,String remoteFile){byte[] fileBytes = null;try {//1. 获取StorageClient对象StorageClient storageClient = getStorageClient();//2.下载文件 返回0表示成功,其它均表示失败fileBytes = storageClient.download_file(group,remoteFile);} catch (IOException e) {e.printStackTrace();} catch (MyException e) {e.printStackTrace();} finally {closeFastDFS();}return fileBytes;
}
⑥ 浏览器访问下载测试效果
- 功能实现-删除某一个债权合同,使用ajax实现异步删除
① 在index.html页面为删除加超链接
<span th:if="${creditorInfo.getGroupname() ne null && creditorInfo.remotefilepath ne null}"><a th:href="@{'/fastdfs/download?id=' + ${creditorInfo.id}}">下载</a><a th:href="@{'javascript:deleteFile('+ ${creditorInfo.id} +')'}">删除</a>
</span>
② 在index.html页面提供js方法,并发送ajax请求,对响应结果进行处理
<script type="text/javascript" th:inline="javascript">function deleteFile(id){//获取项目的上下文根var contextPath = [[${#request.getContextPath()}]];$.ajax({url:contextPath +"/fastdfs/fileDelete",type:"post",data:{"id":id},success:function(responseMsg){if(responseMsg==0){alert("删除成功");window.location.reload();}else{alert("删除失败");}}});}
</script>
③ 在CreditorController中处理删除请求
注意
:删除FastDFS和清除数据库,所以我们将这些业务都放在service中进行事务的处理
@RequestMapping("/fastdfs/fileDelete")
public @ResponseBody String fileDelete(@RequestParam("id") Integer id){int result = 1;try {result = creditorService.deleteContract(id);} catch (Exception e) {e.printStackTrace();}return String.valueOf(result);
}
④ 在CreditorService接口中加删除合同的方法deleteContract
因为目前提供的方法,如果group和remoteFilePath为空就不更新,所以我们需要自己提供
/*** 删除合同* @param id* @return*/
int deleteContract(Integer id);
⑤ 在CreditorServiceImpl类中对deleteContract方法进行实现
@Override
@Transactional //加上该注解控制事务
public int deleteContract(Integer id) {// 1 删除失败;0 删除成功int result = 1;//根据债权id获取债权信息CreditorInfo creditorInfo = creditorInfoMapper.selectByPrimaryKey(id);/*** 注意:事务控制的数据库,所以我们先对数据库进行更新,在操作FastDFS* 如果操作FastDFS失败了,那么对数据库的操作回滚*///更新数据库债权表的合同路径及组int updateRow = creditorInfoMapper.updateConstractById(id);if(updateRow > 0){//如果数据库更新成功,那么删除FastDFS上的文件int num = FastDFS.fileDelete(creditorInfo.getGroupname(),creditorInfo.getRemotefilepath());if(num == 0){//如果删除成功,那么将整个操作结果设置为0,表示成功result = 0;}else{//如果删除FastDFS上的文件失败,我们抛出一个运行异常,回滚事务throw new RuntimeException("FastDFS文件删除失败");}}return result;
}
⑥ 在CreditorMapper类中添加更新的方法
/*** 根据债权的id,将组和合同路径更新为null* @param id* @return*/
int updateConstractById(Integer id);
⑦ 在CreditorMapper.xml中添加更新的方法
<update id="updateConstractById" parameterType="java.lang.Integer">update creditor_infoset groupName = NULL ,remoteFilePath = NULL where id = #{id,jdbcType=INTEGER}
</update>
⑧ 修改FastDFS类中的fileDelete方法,提供参数
//删除文件的方法
public static int fileDelete(String group ,String remoteFile){int num = 1;try {//1. 获取StorageClient对象StorageClient storageClient = getStorageClient();//2.删除文件 返回0表示成功,其它均表示失败num = storageClient.delete_file(group,remoteFile);} catch (IOException e) {e.printStackTrace();} catch (MyException e) {e.printStackTrace();} finally {closeFastDFS();}return num;
}
⑨ 在Application类上开启事务支持
@SpringBootApplication
@EnableTransactionManagement
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
- 功能实现-弹层组建layer的使用(简单介绍)
官网:https://www.layui.com
2018开源软件排行比较靠前
6、FastDFS分布式文件系统集群
6.1 架构图
● 如果你公司刚好用这个,那你就会搭建集群
● 涉及到多个Linux,你可以更进一步熟悉一下Linux
● 提升自己驾驭复杂环境的能力
6.2 环境搭建步骤
建一个FastDFS分布式文件系统集群,推荐至少部署6个服务器节点。
1. 安装6个迷你版的Linux
迷你版Linux没有图形界面,占用磁盘及资源小,企业里面使用的Linux都是没有图形界面的Linux,在安装的时候,最少要给每一个虚拟机分配3.5G的内存空间,我这里分配5G,内存我这里分配的是512M
① 打开Vmware,点击创建新的虚拟机
② 选择典型安装
③ 选择安装Linux迷你版安装文件位置
④ 指定虚拟机名称及安装位置
⑤ 为虚拟机分配磁盘空间
⑥ 为虚拟机分配内存
我是8G内存,每个虚拟机分配512M,因为是迷你版,所以内存消耗不会太大
⑦ 开启此虚拟机
⑧ 开始安装
⑨ 选择语言为English
⑩ 打开网络连接(重要)
这个选项点进去完成一下就好,其它配置都可以默认,但是网络一定要打开,否则虚拟机之间无法通讯
⑪ 设置root用户密码为123456
⑬ 安装完毕后,重启安装的CentOS系统
2. 在Xshell中创建6个连接,分别连向不同的Linux
3. 为迷你版的Linux安装常用工具库
由于迷你版Linux缺少一些常用的工具库,操作起来不方便,推荐安装如下的工具库:
• 安装lrzsz, yum install lrzsz -y
• 安装wget, yum install wget -y
• 安装vim, yum install vim -y
• 安装unzip,yum install unzip -y
• 安装ifconfig,yum install net-tools -y
yum install lrzsz wget vim unzip net-tools –y
打开撰写栏,方便批量执行命令
4. 按照课件上安装FastDFS的步骤在6个服务器节点安装FastDFS
5. 配置两个tracker server服务器
为了方便操作,我们再启动一次Xshell,一个Xshell操作Tracker,另一个操作Storage,将Tracker和Storage分开
• 把/etc/fdfs目录下的配置文件.sample后缀都去掉
• 修改两个tracker服务器的配置文件:
tracker.conf: 修改一个地方:base_path=/opt/fastdfs/tracker #设置tracker的数据文件和日志目录(需预先创建)
• 创建存放数据的目录
6. 配置四个storage server服务器
每两个storage server为一组,共两个组(group1 和 group2),一个组内有两个storage server
① 修改第一组group1的第一个storage server(修改storage.conf配置文件)
group_name=group1 #组名,根据实际情况修改,值为 group1 或 group2base_path=/opt/fastdfs/storage #设置storage的日志目录(需预先创建)store_path0=/opt/fastdfs/storage/files #存储路径tracker_server=192.168.235.129:22122 #tracker服务器的IP地址和端口号,配2个tracker_server=192.168.235.130:22122
② 第一个组的第二个storage按照相同的步骤操作
或者将第一组的配置文件下载到桌面上,然后上传覆盖第一组的第二个storage
③ 第二组的两个storage也按照相同的步骤操作;唯一的区别是group_name=group2
可以在桌面上对第一个组的storage文件进行修改,将组名修改为group2,然后上传覆盖
至此,一个FastDFS的分布式文件系统集群就搭建好了。
④ 注意:配置文件中不要出现中文,另外别忘了创建配置文件中指定的目录
⑤ 启动两个tracker,再启动四个storage
⑥ 关闭6个Linux防火墙,通过09-fastdfs-java的代码进行测试
修改配置文件为两个tracker测试负载均衡:tracker.conf文件 (修改 store_lookup=0 表示轮训策略)
7. 部署Http访问FastDFS上的文件
① 先完成4个storage server的Nginx访问
这4个Nginx需要去fastDFS找对应的文件,所以需要安装FastDFS的Nginx扩展模块
A、 配置带有FastDFS扩展模块的Nginx
在四个storage server上安装Nginx,并且加入FastDFS扩展模块;
修改两组4个storage的nginx扩展模块配置文件 mod_fastdfs.conf
base_path=/opt/fastdfs/nginx_mod #保存日志目录(需提前创建)
tracker_server=192.168.230.129:22122 #tracker服务器的IP地址以及端口号
tracker_server=192.168.230.130:22122
group_name=group1 #当前服务器的group名,第二组应配置为group2
url_have_group_name=true #文件url中是否有group名
store_path_count=1 #存储路径个数,需要和store_path个数匹配(一般不用改)
store_path0=/opt/fastdfs/storage/files #存储路径
group_count = 2 #设置组的个数在末尾增加2个组的具体信息:
[group1]
group_name=group1
storage_server_port=23000
store_path_count=1
store_path0=/opt/fastdfs/storage/files[group2]
group_name=group2
storage_server_port=23000
store_path_count=1
store_path0=/opt/fastdfs/storage/files
B、 第一组的第二台和上面的配置一样
C、 第二组的两台只需要把group_name=group2即可
D、 至此,mod_fastdfs.conf就配置好了。
② 配置两组4个storage的nginx拦截请求路径:
location ~ /group[1-9]/M0[0-9] { ngx_fastdfs_module;
}
至此4个storage服务器上的Nginx就搭建配置OK了
然后可以进行测试:
重启storage,启动Nginx
http://192.168.119.128:80/group1/M00/00/00/wKh3jVx6FUCARyK2AAAANaS4cxw338.txt
http://192.168.92.132:80/group1/M00/00/00/wKhchFv7xQeAQbrBAAAALDPVPvc081.txt
http://192.168.92.133:80/group1/M00/00/00/wKhchFv7xQeAQbrBAAAALDPVPvc081.txt
http://192.168.92.134:80/group1/M00/00/00/wKhchFv7xQeAQbrBAAAALDPVPvc081.txt
注意:每一台都可以访问到,就算是当前组中没有改文件,因为向浏览器中发送请求的时候
交给Nginx进行location匹配
匹配上之后调用FastDFS的扩展模块
扩展模块会读取扩展模块配置文件mod_fast.conf
通过扩展模块配置文件,找到对应的Tracker,从而找到对应的文件
③ 在两个tracker server安装Nginx
这两个Nginx只需要做负载均衡,不要找文件,所以不需要安装扩展模块
④ 配置两个tracker server服务器上的Nginx访问
部署配置nginx负载均衡:
upstream fastdfs_storage_server { server 192.168.92.131:80; server 192.168.92.132:80;server 192.168.92.133:80; server 192.168.92.134:80;
}
#nginx拦截请求路径:
location ~ /group[1-9]/M0[0-9] { proxy_pass http://fastdfs_storage_server;
}
至此,两个tracker服务器的Nginx就搭建配置OK了。
启动两个tracker服务器的Nginx进行测试。
http://192.168.92.129:80/group1/M00/00/00/wKhchFv7xQeAQbrBAAAALDPVPvc081.txt
http://192.168.92.130:80/group1/M00/00/00/wKhchFv7xQeAQbrBAAAALDPVPvc081.txt
⑤ 部署前端用户访问入口服务器,该Nginx负载均衡到后端2个tracker server
这个Nginx也只需要做负载均衡,不要找文件,所以不需要安装扩展模块,可以对Windows上的的Nginx进行配置
部署配置nginx负载均衡:
upstream fastdfs_tracker_server { server 192.168.92.129:80; server 192.168.92.130:80;
}
#nginx拦截请求路径:
location ~ /group[1-9]/M0[0-9] { proxy_pass http://fastdfs_tracker_server;
}
访问:http://127.0.0.1:80/group1/M00/00/00/wKhchFv7xQeAQbrBAAAALDPVPvc081.txt
至此,一个三层结构的Nginx访问架构就搭建配置OK了。为了保证高可用性,一般在入口出,会添加一个备用Nginx上,中间通过一个keepAlive软件连接。
最后,为了让服务能正常连接tracker,请关闭所有机器的防火墙:
systemctl status firewalldsystemctl disable firewalldsystemctl stop firewalld
分布式文件系统----FastDFS相关推荐
- 轻量级分布式文件系统FastDFS使用安装说明手册(新手入门级)
轻量级分布式文件系统FastDFS使用安装说明手册(新手入门级) 实验室所在的课题组以研究云计算为主,但所有的研究都是在基于理论的凭空想像,缺少分布式环境的平台的实践,云计算神马的都是浮云了.因此,我 ...
- 高可用高性能分布式文件系统FastDFS实践Java程序
在前篇 高可用高性能分布式文件系统FastDFS进阶keepalived+nginx对多tracker进行高可用热备 中已介绍搭建高可用的分布式文件系统架构. 那怎么在程序中调用,其实网上有很多栗子, ...
- 分布式文件系统FastDFS架构剖析
文/余庆 FastDFS是一款类Google FS的开源分布式文件系统,它用纯C语言实现,支持Linux.FreeBSD.AIX等UNIX系统.它只能通过专有API对文件进行存取访问,不支持POSIX ...
- 实战:轻量级分布式文件系统FastDFS(GraphicsMagick图片压缩)
轻量级分布式文件系统FastDFS--实现用户头像上传/压缩屏幕适配 一.需求分析 1.1 业务场景: 用户上传的头像图片大小不一.手机和PC等设备显示尺寸也存在差异,因此需要能根据http请求指定的 ...
- (转)淘淘商城系列——分布式文件系统FastDFS
http://blog.csdn.net/yerenyuan_pku/article/details/72801777 商品添加的实现,包括商品的类目选择,即商品属于哪个分类?还包括图片上传,对于图片 ...
- 网站文件系统发展分布式文件系统fastDFS
网站文件系统发展 1.单机时代的图片服务器架构 初创时期由于时间紧迫,开发人员水平也很有限等原因.所以通常就直接在website文件所在的目录下,建立1个upload子目录,用于保存用户上传的图片文件 ...
- 分布式文件系统FastDFS详解-附带视频教程
目录 1.FastDFS教程 2.FastDFS安装 安装FastDFS FastDFS配置文件详解 FastDFS启动 3.FastDFS重启与FastDFS关闭 FastDFS关闭 4.FastD ...
- 分布式文件系统Fastdfs 详细安装笔记
简介 FastDFS是一款类Google FS的开源分布式文件系统,它用纯C语言实现,支持Linux.FreeBSD.AIX等UNIX系统.它只能通过专有API对文件进行存取访问,不支持POSIX接口 ...
- CentOS7下分布式文件系统FastDFS的安装 配置 (单节点)
背景 FastDFS是一个开源的轻量级分布式文件系统,为互联网量身定制,充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高性能等指标,解决了大容量存储和负载均衡的问题,特别适合以文件为载体 ...
最新文章
- 转自微信号:测试那点事
- PyTorch + NumPy这么做会降低模型准确率,这是bug还是预期功能?
- c语言分组求和函数,R语言 实现data.frame 分组计数、求和等
- [费用流]数字配对,新生舞会
- dynamic 365 js 失去焦点_基于Auto.js的QQ好友动态秒赞系统
- (14)System Verilog范围随机函数
- Sharepoint学习笔记—习题系列--70-573习题解析 -(Q136-Q138)
- Lotus Notes 中导航的键盘快捷方式
- CacheCloud详解(一)----------CacheCloud搭建(Redis云平台)
- 用C++写一个班级通讯录管理软件
- 华为鸿蒙如何添加桌面小组件,万能小组件添加至桌面怎么弄?桌面添加应用方法图文详解...
- keep be curious
- Git:Terminal is dumb, but EDITOR unset
- Python将txt数据写入excel【分列】
- MathType 如何安装成功以及如何导入word
- 祝福老婆今晚不要太生气
- 微软裁员和.NET的开源
- flash builder (fb) 与flash professional cs6(fla) 联合调试
- 苹果pencil值得买吗?苹果平板电容笔推荐
- mega raid linux,在lsi megaraid sas 8204elp 装linux系统(未完待续)
热门文章
- 计算机桌面屏幕显示不到右边,电脑显示器没有满屏怎么回事
- Android 获取屏幕大小以及尺寸
- 用selenium模拟登录百度
- 80端口是什么服务使用的?80端口和443端口是默认开启的吗?
- 跟踪事件oracle,Oracle的10046事件跟踪简述
- modelsim新建工程进行功能仿真
- [转]php中流行的rpc框架有哪些?
- 易语言-API 取窗口或者组件句柄的 屏幕坐标并限制区域 GetWindowRect ClipCursor getwindowrect GetClientRect WindowFromPoint
- 实现 await UnityWebRequest
- CSDN网站个性化推荐功能测试