分布式文件系统fastDFS

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


第1章FastDFS入门

1.1分布式文件系统

  • 分布式文件系统 (Distributed File System) 是一个软件/软件服务器,这个软件可以用来管理文件。但这个软件所管理的文件通常不是在一个服务器节点上,而是在多个服务器节点上,这些服务器节点通过网络相连构成一个庞大的文件存储服务器集群,这些服务器都用于存储文件资源,通过分布式文件系统来管理这些服务器上的文件。

  • 常见的分布式文件系统有:FastDFS、GFS、HDFS、Lustre 、Ceph 、GridFS 、mogileFS、TFS等。

  • 分布式文件系统与传统文件系统对比

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

传统方式弊端

  • 如果用户数量多,IO操作比较多,对磁盘访问压力很大
  • 如果磁盘发生故障,会造成数据丢失
  • 存储容量有限

1.2FastDFS简介

FastDFS是一个开源的轻量级分布式文件系统,为互联网应用量身定做,简单、灵活、高效,采用C语言开发,由阿里巴巴开发并开源。

FastDFS对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载、文件删除)等,解决了大容量文件存储的问题,特别适合以文件为载体的在线服务,如相册网站、文档网站、图片网站、视频网站等等。

FastDFS充分考虑了冗余备份、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

1.3FastDFS发展历史

2008年4月项目启动,7月发布第一个版本V1.00,两年时间内持续升级到V1.29
2010年8月推出V2.00
2011年6月推出V3.00
2012年10月推出V4.0.0
2013年12月推出V5.0.0
截止目前最新版是V5.11(2017年6月发布)
FastDFS系统架构从第一个版本发布后一直没有大的调整,高版本完全兼容低版本的数据,可以做到平滑升级,推荐更新升级到最新版本
FastDFS代码托管在github上:https://github.com/happyfish100/fastdfs

1.4FastDFS整体架构

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)都保存到存储服务器磁盘上,完成文件管理的所有功能:文件存储、文件同步和提供文件访问等。

    在这里插入图片描述

第2章FastDFS环境搭建

2.1FastDFS安装

2.1.1安装前的准备

(1)检查Linux上是否安装了 gcc、libevent、libevent-devel

yum list installed | grep gcc
yum list installed | grep libevent
yum 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文件上传到Linuxs(/home/soft)
在这里插入图片描述

(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

在这里插入图片描述

至此 libfastcommon 库安装完毕

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/soft)
在这里插入图片描述

(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

在这里插入图片描述

至此FastDFS安装完成
所有编译出来的文件存放在/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.2FastDFS配置

2.2.1去掉/etc/fdfs/目录下FastDFS配置文件的后缀名

在这里插入图片描述

2.2.2修改tracker.conf文件

默认指向的FastDFS作者余庆的目录,因为在我们的机器上不存在,所有手动改一下

base_path=/opt/fastdfs/tracker		#配置tracker存储数据的目录

在这里插入图片描述

2.2.3修改storage.conf文件

base_path=/opt/fastdfs/storage 			#storage存储数据目录
	store_path0=/opt/fastdfs/storage/files 	#真正存放文件的目录
	tracker_server=192.168.235.128:22122 	#注册当前存储节点的跟踪器地址

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2.4在Linux服务器上创建上面指定的目录

/opt/fastdfs/tracker
/opt/fastdfs/storage
/opt/fastdfs/storage/files

在这里插入图片描述

2.2.5然后启动FastDFS

2.3FastDFS启动

FastDFS服务启动需要启动两个脚本:

2.3.1启动FastDFS的tracker服务

在任意目录下执行:fdfs_trackerd /etc/fdfs/tracker.conf
在这里插入图片描述

2.3.2启动FastDFS的storage服务

在任意目录下执行:fdfs_storaged /etc/fdfs/storage.conf
在这里插入图片描述

2.3.3查看启动进程

在这里插入图片描述

有启动的执行命令即为启动成功

2.3.4查看storage是否已经注册到了tracker下

fdfs_monitor /etc/fdfs/storage.conf
在这里插入图片描述

2.3.5首次启动storage后,会在配置的路径下创建存储文件的目录

在这里插入图片描述

2.4FastDFS重启

2.4.1重启tracker

fdfs_trackerd /etc/fdfs/tracker.conf restart

在这里插入图片描述

2.4.2重启storage

fdfs_storaged /etc/fdfs/storage.conf restart

在这里插入图片描述

2.5FastDFS关闭

2.5.1关闭tracker执行命令

在任意目录下执行:fdfs_trackerd /etc/fdfs/tracker.conf stop
在这里插入图片描述

2.5.2关闭storage执行命令

在任意目录下执行:fdfs_storaged /etc/fdfs/storage.conf stop
在这里插入图片描述

2.5.3或者kill关闭fastdfs,但不建议在线上使用 kill -9 强制关闭,因为可能会导致文件信息不同步问题

2.6FastDFS测试

FastDFS安装完成之后,可以使用fdfs_test脚本测试文件上传

2.6.1测试之前,需要修改client.conf配置文件,修改两个配置

base_path=/opt/fastdfs/client
tracker_server=192.168.179.128:22122

在这里插入图片描述
在这里插入图片描述

  • 在/opt/fastdfs/目录下创建client
    在这里插入图片描述

2.6.2测试文件上传

  • 准备需要上传的文件
    在这里插入图片描述

  • 执行上传命令fdfs_test /etc/fdfs/client.conf upload /root/aa.txt
    在这里插入图片描述

  • 切换到存储目录查看文件上传情况
    在这里插入图片描述

2.6.3FastDFS生成的文件目录结构及名称示例

在这里插入图片描述

2.6.4测试文件删除

fdfs_delete_file /etc/fdfs/client.conf group1/要删除的文件路径

在这里插入图片描述

2.6.5注意

  • 没有搭建集群默认只有一个组group1
  • 后缀名包含-m的为属性文件(meta)
  • 在Linux中并没有磁盘一说,是虚拟的

第3章分布式文件系统FastDFS的HTTP访问

3.1概述

在文件上传的时候,上传成功的信息中有提示我们可以通过某个路径去访问上传的文件,但是我们直接访问这个路径,却不可以,那么已经上传到FastDFS文件系统中的文件,我们如何在浏览器中访问呢?

FastDFS提供了一个Nginx扩展模块,利用该模块,我们可以通过Nginx访问已经上传到FastDFS上的文件

3.2前期准备工作

3.2.1将Fastdfs的Nginx扩展模块源代码上传到Linux上

在这里插入图片描述

3.2.2解压下载下来的fastdfs-nginx-module-master.zip 文件

unzip fastdfs-nginx-module-master.zip

在这里插入图片描述

3.3安装Nginx并且添加fastDFS模块

因为这个模块必须在Nginx的安装的过程中才能添加,所有我们需要重新安装一个nginx,为了和原来已安装的Nginx进行区分,我们把新安装的Nginx取名为nginx_fdfs

3.3.1将Nginx的tar包上传到Linux上在这里插入图片描述

3.3.2解压上传的Nginx文件

在这里插入图片描述

3.3.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模块的源代码路径

在这里插入图片描述

3.3.4执行命令进行编译

make

3.3.5执行命令进行安装

make install

3.3.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

3.4FastDFS的Nginx访问配置

3.4.1将/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/

在这里插入图片描述

3.4.2修改mod_fastdfs.conf配置文件

base_path=/opt/fastdfs/nginx_mod
	tracker_server=192.168.235.128:22122
url_have_group_name = true
store_path0=/opt/fastdfs/storage/files

3.4.3在/opt/fastdfs/目录下创建nginx_mod目录在这里插入图片描述

3.4.4配置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.5FastDFS的Nginx访问启动与测试

3.5.1启动带有Fastdfs模块的Nginx

在这里插入图片描述

3.5.2重启或启动FastDFS服务进程

fdfs_trackerd /etc/fdfs/tracker.conf restart
fdfs_storaged /etc/fdfs/storage.conf restart
在这里插入图片描述

3.5.3上传一个文件进行测试验证

fdfs_test /etc/fdfs/client.conf upload /root/aa.txt
在这里插入图片描述

3.5.4在浏览器访问上传的文件

当遇到400错误,检查配置/etc/fdfs/mod_fastdfs.conf url_have_group_name=true
该配置表示访问路径中是否需要带有group1,改为true表示路径中需要有group1

3.5.5扩展

模拟大型网站用户头像的处理方式,上传一张图片,然后自己写一个html页面,src指向上传的图片

在这里插入图片描述

第4章FastDFS在Java项目中开发示例

4.1在实际项目开发中,FastDFS提供的主要功能

  • upload:上传文件
  • download:下载文件
  • delete:删除文件

4.2FastDFS文件系统的Java客户端

FastDFS文件系统Java客户端是指采用Java语言编写的一套程序,专门用来访问fastDFS文件系统,其实就是一个jar包。
注意:大家如果能连上 mvnrepository上搜索到的用友云提供的fastdfs-client,那大家就下载那个jar包使用,如果连不上,这个jar包需要我们自己来打

4.2.1下载官方的源代码

从https://codeload.github.com/happyfish100/fastdfs-client-java/zip/master 上下载FastDFS源代码到本地

4.2.2解压

在这里插入图片描述

4.2.3采用maven命令编译成jar安装到本地maven库

mvn clean install

在这里插入图片描述

4.2.4在Java程序中使用它提供的API来访问FastDFS文件系统

4.3文件上传功能的实现

4.3.1需求

使用Java客户端,编程操作fastDFS分布式文件系统,上传本地文件到FastDFS服务器上

4.3.2实现步骤

(1)使用IDEA创建普通的maven项目,不需要使用
在这里插入图片描述

在这里插入图片描述

(2)在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>
可以在这查看jar包里面的内容
![在这里插入图片描述](https://img-blog.csdnimg.cn/02b70f6b24fc4d0c9b3368acf9343cf5.png)

(3)拷贝源代码包中的fdfs_client.conf文件到resources目录下,在里面主要配置tracker地址
在这里插入图片描述

tracker_server = 192.168.235.128:22122

(4)编写代码,进行上传测试
在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();
                }
            }
        }
    }
}

(5)运行程序,在Linux上,FastDFS存储目录下查看上传文件内容
在这里插入图片描述
在这里插入图片描述

4.4将文件上传功能中的公共代码进行封装

(1)需求
因为使用FastDFS进行文件操作代码大多都是通用的,所以我们这里在FastDFS类中将通用的功能进行封装,并提供上传、下载、删除文件的方法
注意:这里只是简单的封装,如果多线程会有问题
(2)实现步骤
A、抽取获取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;
}

B、定义两个全局变量

private static TrackerServer trackerServer = null;
private static StorageServer storageServer = null;

C、抽取关闭资源的方法

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();
        }
    }
}

D、改造文件上传的方法

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();
    }
}

E、下载文件的方法

//下载文件的方法
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();
    }
}

F、删除文件的方法

//删除文件的方法
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();
    }
}

G、主方法调用不同的方法进行测试

第5章FastDFS在web项目中的应用

5.1需求

对P2P项目合同进行管理,在WEB项目中实现对文件的上传下载和删除操作

5.2名词解释

  • 有一些债权:投资人有该债务的权利
    通常隐含的意思就是:一笔借款常被称为一个债权
  • 一个债权会有一个合同
  • 合同是pdf文件
  • 债权是债务的对应词,但是在P2P项目中,我们管理的债权,以及合同一般指的是借款人的信息,所以在我们下面创建的creditor_info表中存的是借款人信息

5.3目标

  • 实现对pdf文件上传、下载、删除
  • 熟练一下Springboot+thymeleaf

5.4案例实现步骤

5.4.1数据库环境搭建

(1)创建数据库fastdfs
在这里插入图片描述

(2)在该库下创建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

5.4.2开发环境搭建

(1)创建SpringBoot项目10-fastdfs-web,添加Web和Thymeleaf依赖

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(2)在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>

(3)在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>

(4)在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

(5)使用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 generatorConfiguration
        PUBLIC "-//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>
        <!-- 生成MyBatisMapper.xml文件,targetPackage指定mapper.xml文件的包名, targetProject指定生成的mapper.xml放在eclipse的哪个工程下面 -->
        <sqlMapGenerator targetPackage="com.bjpowernode.fastdfs.mapper" targetProject="src/main/java">
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>
        <!-- 生成MyBatisMapper接口类文件,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、双击生成
在这里插入图片描述

(6)创建相关的包和类

  • 在com.bjpowernode.fast包下创建controller ,service 包,及其子包impl
  • 创建CreditorInfoController类
  • 创建CreditorInfoService接口
  • 创建CreditorInfoServiceImpl实现类

5.4.3功能实现-展示所有债权信息

(1)在CreditorInfoController类中创建index方法,将CreditorInfoService注入到controller中

@Controller
public class CreditorInfoController {
    @Autowired
    private CreditorInfoService creditorInfoService;

    @GetMapping("/fastdfs/index")
    public String index(Model model){
        List<CreditorInfo> creditorInfoList = creditorInfoService.getAllCreditorInfo();
        model.addAttribute("creditorInfoList",creditorInfoList);
        //模板页面,不是jsp
        return "index";
    }
}

(2)在CreditorInfoService中提供getAllCreditorInfo方法

public interface CreditorInfoService {
    /**
     * 获取所有债权信息
     * @return
     */
    List<CreditorInfo> getAllCreditorInfo();
}

(3)在CreditorInfoServiceImpl中对getAllCreditorInfo方法进行实现

@Service
public class CreditorInfoServiceImpl implements CreditorInfoService {
    @Autowired
    private CreditorInfoMapper creditorInfoMapper;
    @Override
    public List<CreditorInfo> getAllCreditorInfo() {
        return creditorInfoMapper.selectAllCreditorInfo();
    }
}

(4)因为是SpringBoot项目,所以需要在Mapper接口上加一个Mapper注解

@Mapper
public interface CreditorInfoMapper {

(5)在CreditorInfoMapper类中添加selectAllCreditorInfo方法

List<CreditorInfo> selectAllCreditorInfo();

(6)在IDEA中安装free Mybatis插件
该插件可以通过点击Mapper接口中的方法,进入到.xml文件
A、SettingspluginsBrowse repositories
在这里插入图片描述

B、在插件库中搜索,free mybatis安装
在这里插入图片描述

C、插件安装完毕,需要重启IDEA
(7)在CreditorInfoMapper.xml文件中添加SQL语句

<select id="selectAllCreditorInfo" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from creditor_info
</select>

(8)展示页面的设计
A、在项目的templates目录下创建index.html
在这里插入图片描述

B、百度搜索bootstrap表格,挑选自己喜欢风格的表格,将代码拷贝到index.html中
我这里使用的是http://www.runoob.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的相关目录下,在页面上引用
(9)向数据库中加几条数据
在这里插入图片描述

(10)启动项目,访问http://localhost:8080/fastdfs/index 查看效果
在这里插入图片描述

(11)调整页面样式

<body style="margin: 50px">

5.4.4功能实现-为某一个债权合同上传文件
(1)在index.html中添加操作列

<th>合同管理</th>

<td>
    <!--为哪个合同上传,需要将合同的id传递过去-->
    <a th:href="@{'/fastdfs/toUpload?id=' + ${creditorInfo.id}}">上传</a>
    下载
    删除
</td>

(2)在CreditorController中添加跳转到上传页面的方法

@GetMapping("/fastdfs/toUpload")
public String toUpload(Model model, @RequestParam("id") Integer id){
    model.addAttribute("id",id);
    return "upload";
}

(3)在templates下创建upload.html页面
在网上搜索bootstrap表单,并对其内容进行修改,我这里使用的是
http://www.runoob.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通过隐藏域传递

(4)在pom.xml文件中加入FastDFS客户端的jar包依赖

<!--加入FastDFS的java客户端依赖-->
<dependency>
   <groupId>org.csource</groupId>
   <artifactId>fastdfs-client-java</artifactId>
   <version>1.27-SNAPSHOT</version>
</dependency>

(5)将FastDFS客户端的配置文件fast_client.conf拷贝到resources目录下
在这里插入图片描述

(6)将原来我们封装的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;
}

(7)在CreditorController中添加处理上传文件的方法

@PostMapping("/fastdfs/upload")
public @ResponseBody String upload(@RequestParam("id") Integer id, @RequestParam("fileName") MultipartFile file){
    //原来文件上传是将文件写到本地或者远程服务器的某个目录下
    //现在的文件上传是将文件上传到fastdfs文件服务器上
    //1表示上传失败  0表示成功
    int result = 1;
    //abc.txt -->txt
    String 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>";
}

(8)在CreditorInfoService中添加updateCreditorInfo方法

/**
 * 更新债权信息
 * @param creditorInfo
 * @return
 */
int updateCreditorInfo(CreditorInfo creditorInfo);

(9)在CreditorInfoServiceImpl中添加updateCreditorInfo方法实现

@Override
public int updateCreditorInfo(CreditorInfo creditorInfo) {
    return creditorInfoMapper.updateByPrimaryKeySelective(creditorInfo);
}

(10)在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>

(11)如果上传文件超出了1M,需要在application.properties中配置SpringBoot上传文件的最大限制

#SpringBoot上传文件的最大限制
spring.servlet.multipart.max-file-size=10MB

注意:如果提示找不到tracker_server,看看是否编译到target中

5.4.5功能实现-下载某一个债权合同

(1)修改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>

(2)在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;
}

(3)在CreditorService接口中添加getCreditorInfoById的方法

/**
 * 根据合同id获取债权信息
 * @param id
 * @return
 */
CreditorInfo getCreditorInfoById(Integer id);

(4)在CreditorServiceImpl中添加getCreditorInfoById方法的实现

@Override
public CreditorInfo getCreditorInfoById(Integer id) {
    return creditorInfoMapper.selectByPrimaryKey(id);
}

(5)修改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;
}

(6)浏览器访问下载测试效果

5.4.6功能实现-删除某一个债权合同,使用ajax实现异步删除

(1)在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>

(2)在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>

(3)在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);
}

(4)在CreditorService接口中加删除合同的方法deleteContract
因为目前提供的方法,如果group和remoteFilePath为空就不更新,所以我们需要自己提供

/**
 * 删除合同
 * @param id
 * @return
 */
int deleteContract(Integer id);

(5)在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;
}

(6)在CreditorMapper类中添加更新的方法

/**
 * 根据债权的id,将组和合同路径更新为null
 * @param id
 * @return
 */
int updateConstractById(Integer id);

(7)在CreditorMapper.xml中添加更新的方法

<update id="updateConstractById" parameterType="java.lang.Integer">
  update creditor_info
  set 
  groupName = NULL ,
  remoteFilePath = NULL 
  where id = #{id,jdbcType=INTEGER}
</update>

(8)修改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; 
}

(9)在Application类上开启事务支持

@SpringBootApplication
@EnableTransactionManagement
public class Application {
   public static void main(String[] args) {
      SpringApplication.run(Application.class, args);
   }
}

5.4.7功能实现-弹层组建layer的使用(简单介绍)

官网:https://www.layui.com/
2018开源软件排行比较靠前

第6章FastDFS分布式文件系统集群

6.1架构图
在这里插入图片描述

  • 如果你公司刚好用这个,那你就会搭建集群
  • 涉及到多个Linux,你可以更进一步熟悉一下Linux
  • 提升自己驾驭复杂环境的能力

6.2环境搭建步骤

搭建一个FastDFS分布式文件系统集群,推荐至少部署6个服务器节点

6.2.1安装6个迷你版的Linux

迷你版Linux没有图形界面,占用磁盘及资源小,企业里面使用的Linux都是没有图形界面的Linux,在安装的时候,最少要给每一个虚拟机分配3.5G的内存空间,我这里分配5G,内存我这里分配的是512M
(1)打开Vmware,点击创建新的虚拟机
在这里插入图片描述

(2)选择典型安装
在这里插入图片描述

(3)选择安装Linux迷你版安装文件位置
在这里插入图片描述

(4)指定虚拟机名称及安装位置
在这里插入图片描述

(5)为虚拟机分配磁盘空间
在这里插入图片描述

(6)为虚拟机分配内存
我是8G内存,每个虚拟机分配512M,因为是迷你版,所以内存消耗不会太大
在这里插入图片描述

(7)开启此虚拟机
在这里插入图片描述

(8)开始安装
在这里插入图片描述

(9)选择语言为English
在这里插入图片描述

(10)打开网络连接(重要)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这个选项点进去完成一下就好,其它配置都可以默认,但是网络一定要打开,否则虚拟机之间无法通讯
(11)设置root用户密码为123456
在这里插入图片描述

(12)创建普通用户centos,设置密码为123456
在这里插入图片描述

(13)安装完毕后,重启安装的CentOS系统

6.2.2在Xshell中创建6个连接,分别连向不同的Linux

在这里插入图片描述

6.2.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
    打开撰写栏,方便批量执行命令
    在这里插入图片描述

6.2.4按照课件上安装FastDFS的步骤在6个服务器节点安装FastDFS

6.2.5配置两个tracker server服务器

为了方便操作,我们再启动一次Xshell,一个Xshell操作Tracker,另一个操作Storage,

将Tracker和Storage分开

  • 把/etc/fdfs目录下的配置文件.sample后缀都去掉
  • 修改两个tracker服务器的配置文件:
    tracker.conf: 修改一个地方:
    base_path=/opt/fastdfs/tracker #设置tracker的数据文件和日志目录(需预先创建)
  • 创建存放数据的目录

6.2.6配置四个storage server服务器

每两个storage server为一组,共两个组(group1 和 group2),一个组内有两个storage server

(1)修改第一组group1的第一个storage server(修改storage.conf配置文件)

group_name=group1 #组名,根据实际情况修改,值为 group1 或 group2
base_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

(2)第一个组的第二个storage按照相同的步骤操作
或者将第一组的配置文件下载到桌面上,然后上传覆盖第一组的第二个storage
(3)第二组的两个storage也按照相同的步骤操作;唯一的区别是group_name=group2
可以在桌面上对第一个组的storage文件进行修改,将组名修改为group2,然后上传覆盖
至此,一个FastDFS的分布式文件系统集群就搭建好了。
(4)注意:配置文件中不要出现中文,另外别忘了创建配置文件中指定的目录
(5)启动两个tracker,再启动四个storage
(6)关闭6个Linux防火墙,通过09-fastdfs-java的代码进行测试

  • 修改配置文件为两个tracker
  • 测试负载均衡:tracker.conf文件 (修改 store_lookup=0 表示轮训策略)

6.2.7部署Http访问FastDFS上的文件

(1)先完成4个storage server的Nginx访问
这4个Nginx需要去fastDFS找对应的文件,所以需要安装FastDFS的Nginx扩展模块
A、配置带有FastDFS扩展模块的Nginx
1、在四个storage server上安装Nginx,并且加入FastDFS扩展模块;
2、修改两组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就配置好了。
(2)配置两组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,从而找到对应的文件

(3)在两个tracker server安装Nginx

这两个Nginx只需要做负载均衡,不要找文件,所以不需要安装扩展模块

(4)配置两个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进行测试。


```csharp
http://192.168.92.129:80/group1/M00/00/00/wKhchFv7xQeAQbrBAAAALDPVPvc081.txt
http://192.168.92.130:80/group1/M00/00/00/wKhchFv7xQeAQbrBAAAALDPVPvc081.txt

(5)部署前端用户访问入口服务器,该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 firewalld
systemctl disable firewalld
systemctl stop firewalld

	



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值