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 前期准备工作

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

  2. 解压下载下来的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 实现步骤

  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>
  1. 拷贝源代码包中的fdfs_client.conf文件到resources目录下,在里面主要配置tracker地址
tracker_server = 192.168.235.128:22122
  1. 编写代码,进行上传测试
    在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();}}}}
}
  1. 运行程序,在Linux上,FastDFS存储目录下查看上传文件内容

4.3 FastDFS文件上传功能封装

4.3.1 需求

因为使用FastDFS进行文件操作代码大多都是通用的,所以我们这里在FastDFS类中将通用的功能进行封装,并提供上传、下载、删除文件的方法。

注意:这里只是简单的封装,如果多线程会有问题

4.3.2 实现步骤

  1. 抽取获取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;
}
  1. 定义两个全局变量
private static TrackerServer trackerServer = null;
private static StorageServer storageServer = null;
  1. 抽取关闭资源的方法
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();}}
}
  1. 改造文件上传的方法
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();}
}
  1. 下载文件的方法
/下载文件的方法
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();}
}
  1. 删除文件的方法
/删除文件的方法
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();}
}
  1. 主方法调用不同的方法进行测试

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">
  1. 功能实现-为某一个债权合同上传文件

① 在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中

  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>

② 在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;
}

⑥ 浏览器访问下载测试效果

  1. 功能实现-删除某一个债权合同,使用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);}
}
  1. 功能实现-弹层组建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相关推荐

  1. 轻量级分布式文件系统FastDFS使用安装说明手册(新手入门级)

    轻量级分布式文件系统FastDFS使用安装说明手册(新手入门级) 实验室所在的课题组以研究云计算为主,但所有的研究都是在基于理论的凭空想像,缺少分布式环境的平台的实践,云计算神马的都是浮云了.因此,我 ...

  2. 高可用高性能分布式文件系统FastDFS实践Java程序

    在前篇 高可用高性能分布式文件系统FastDFS进阶keepalived+nginx对多tracker进行高可用热备 中已介绍搭建高可用的分布式文件系统架构. 那怎么在程序中调用,其实网上有很多栗子, ...

  3. 分布式文件系统FastDFS架构剖析

    文/余庆 FastDFS是一款类Google FS的开源分布式文件系统,它用纯C语言实现,支持Linux.FreeBSD.AIX等UNIX系统.它只能通过专有API对文件进行存取访问,不支持POSIX ...

  4. 实战:轻量级分布式文件系统FastDFS(GraphicsMagick图片压缩)

    轻量级分布式文件系统FastDFS--实现用户头像上传/压缩屏幕适配 一.需求分析 1.1 业务场景: 用户上传的头像图片大小不一.手机和PC等设备显示尺寸也存在差异,因此需要能根据http请求指定的 ...

  5. (转)淘淘商城系列——分布式文件系统FastDFS

    http://blog.csdn.net/yerenyuan_pku/article/details/72801777 商品添加的实现,包括商品的类目选择,即商品属于哪个分类?还包括图片上传,对于图片 ...

  6. 网站文件系统发展分布式文件系统fastDFS

    网站文件系统发展 1.单机时代的图片服务器架构 初创时期由于时间紧迫,开发人员水平也很有限等原因.所以通常就直接在website文件所在的目录下,建立1个upload子目录,用于保存用户上传的图片文件 ...

  7. 分布式文件系统FastDFS详解-附带视频教程

    目录 1.FastDFS教程 2.FastDFS安装 安装FastDFS FastDFS配置文件详解 FastDFS启动 3.FastDFS重启与FastDFS关闭 FastDFS关闭 4.FastD ...

  8. 分布式文件系统Fastdfs 详细安装笔记

    简介 FastDFS是一款类Google FS的开源分布式文件系统,它用纯C语言实现,支持Linux.FreeBSD.AIX等UNIX系统.它只能通过专有API对文件进行存取访问,不支持POSIX接口 ...

  9. CentOS7下分布式文件系统FastDFS的安装 配置 (单节点)

    背景 FastDFS是一个开源的轻量级分布式文件系统,为互联网量身定制,充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高性能等指标,解决了大容量存储和负载均衡的问题,特别适合以文件为载体 ...

最新文章

  1. 转自微信号:测试那点事
  2. PyTorch + NumPy这么做会降低模型准确率,这是bug还是预期功能?
  3. c语言分组求和函数,R语言 实现data.frame 分组计数、求和等
  4. [费用流]数字配对,新生舞会
  5. dynamic 365 js 失去焦点_基于Auto.js的QQ好友动态秒赞系统
  6. (14)System Verilog范围随机函数
  7. Sharepoint学习笔记—习题系列--70-573习题解析 -(Q136-Q138)
  8. Lotus Notes 中导航的键盘快捷方式
  9. CacheCloud详解(一)----------CacheCloud搭建(Redis云平台)
  10. 用C++写一个班级通讯录管理软件
  11. 华为鸿蒙如何添加桌面小组件,万能小组件添加至桌面怎么弄?桌面添加应用方法图文详解...
  12. keep be curious
  13. Git:Terminal is dumb, but EDITOR unset
  14. Python将txt数据写入excel【分列】
  15. MathType 如何安装成功以及如何导入word
  16. 祝福老婆今晚不要太生气
  17. 微软裁员和.NET的开源
  18. flash builder (fb) 与flash professional cs6(fla) 联合调试
  19. 苹果pencil值得买吗?苹果平板电容笔推荐
  20. mega raid linux,在lsi megaraid sas 8204elp 装linux系统(未完待续)

热门文章

  1. 计算机桌面屏幕显示不到右边,电脑显示器没有满屏怎么回事
  2. Android 获取屏幕大小以及尺寸
  3. 用selenium模拟登录百度
  4. 80端口是什么服务使用的?80端口和443端口是默认开启的吗?
  5. 跟踪事件oracle,Oracle的10046事件跟踪简述
  6. modelsim新建工程进行功能仿真
  7. [转]php中流行的rpc框架有哪些?
  8. 易语言-API 取窗口或者组件句柄的 屏幕坐标并限制区域 GetWindowRect ClipCursor getwindowrect GetClientRect WindowFromPoint
  9. 实现 await UnityWebRequest
  10. CSDN网站个性化推荐功能测试