一、为什么需要FastDFS文件服务器
去做一个图片的统一处理,那又为什么要统一处理
1.1 传统的图片上传
直接把图片保存到项目的里面的一个文件目录中,生成一个随机的名字,数据库表中需要保存这个图片的路径,页面就会根据对应的路径去显示图片
问题:
1、传统方式图片是交给Tomcat来处理的,Tomcat对图片的出来不占优,比较慢
2、图片或者其他文件会占用太多的项目服务器的磁盘空间,就会导致项目比较庞大,臃肿
3、后台管理平台上传的图片,前台门户网站的拿不到,因为一般图片文件都会放在后台的管理平台中的webapp目录下,当然也可以使用一个中转目录进行图片的复制(后台->中转目录->前台),这样的话性能就会很低了
1.2 文件进行统一处理
当在图片/文件比较多的项目,我们会为了减轻项目服务器对图片处理的压力,一般会把图片/文件进行统一处理,把图片上传到云服务器中,对图片/文件的浏览也直接取访问云服务器,我们自己的项目本身不存储图片/文件,项目的数据库就只对图片/文件的路径进行存储
那问题来了:
1、文件服务器众多,该如何选择,怎么去操作
2、java代码怎么对接文件服务器
3、如何实现文件上传下载
4、数据库如何存储图片路径
1.3 方案选择
选择合适分布式文件系统.
分布式文件系统:多个文件系统通过管理软件进行管理,得到分布式文件系统
好处:
(1)海量存储
(2)高可用
方案1:租用别人已经搭建好了的
比如:阿里云对象存储(收费),七牛云(10G内免费)等等
好处:方便,小量数据可以
坏处:大量数据时,要花很多钱
方案2:自己手动搭建
比如:hdfs(hadoop),FastDfs(国产,小文件)等等
这里我们就自己手动搭建一个FastDFS文件服务器
自己动手丰衣足食,其实还不是因为穷
1.4 分布式文件服务器实现步骤
二、什么是FastDFS文件服务器
2.1 FastDFS介绍
FastDFS 是用 c 语言编写的一款开源的分布式文件系统。FastDFS 为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用 FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
FastDFS 架构包括 Tracker server 和 Storage server。客户端请求 Tracker server 进行文件上传、下载,通过 Tracker server 调度最终由 Storage server 完成文件上传和下载。
Tracker server 作用是负载均衡和调度,通过 Tracker server 在文件上传时可以根据一些策略找到 Storage server 提供文件上传服务。可以将 tracker 称为追踪服务器或调度服务器。
Storage server 作用是文件存储,客户端上传的文件最终存储在 Storage 服务器上,Storageserver 没有实现自己的文件系统而是利用操作系统 的文件系统来管理文件。可以将storage称为存储服务器。
服务端两个角色:
Tracker:管理集群,tracker 也可以实现集群。每个 tracker 节点地位平等。收集 Storage 集群的状态。
Storage:实际保存文件 Storage 分为多个组,每个组之间保存的文件是不同的。每个组内部可以有多个成员,组成员内部保存的内容是一样的,组成员的地位是一致的,没有主从的概念。
参考:
官方网站:https://github.com/happyfish100/
配置文档:https://github.com/happyfish100/fastdfs/wiki/
Java客户端:https://github.com/happyfish100/fastdfs-client-java
官方文档操作写的很详细,按照它的步骤去进行搭建基本是没有问题的
2.2 上传和下载流程
上传
客户端上传文件后存储服务器将文件 ID 返回给客户端,此文件 ID 用于以后访问该文件的索引信息。文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名。
比如:http://192.168.xx.xx:8888/group1/M00/00/00/wKgfJF8ZBQ6ADXLgAABWnR-RCJ0193.jpg
① 当然如果想要访问FastDFS文件服务器里面的图片,最前面肯定要先跟你虚拟机的IP地址和自己配的端口号(这个后面都有讲的)
② 组名(/group1):文件上传后所在的 storage 组名称,在文件上传成功后有 storage 服务器返回,需要客户端自行保存。
③ 虚拟磁盘路径(/M00):storage 配置的虚拟路径,与磁盘选项 store_path*对应。如果配置了store_path0 则是 M00,如果配置了 store_path1 则是 M01,以此类推。
④ 数据两级目录(/00/00):storage 服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据
文件。
⑤ 文件名(/wKgfJF8ZBQ6ADXLgAABWnR-RCJ0193.jpg):与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储
服务器 IP 地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息。
下载
三、环境准备
当然也可以参考官方的配置文档:https://github.com/happyfish100/fastdfs/wiki/
文档里面写的也很详细,我也是参考文档一步一步来进行操作的
3.1 使用的系统软件
我这里使用的是CentOS7.2,nginx是nginx1.15.4,当然还需要libfastcommon(FastDFS分离出的一些公用函数包),FastDFS(FastDFS本体),fastdfs-nginx-module(FastDFS和nginx的关联模块)
有网的同学就可以直接在虚拟机上进行在线下载安装就好了,如果是在无网的环境下操作,那就只有先把相关的系统软件下好,然后手动添加到虚拟机上了,下载地址是话,在下面相关操作步骤中会有的
提示:以下这些代码块中的代码都是在虚拟机的控制台上进行操作的,如果有安装Xshell的话,当然也可以在Xshell中操作,在操作的时候尽量切换成root用户进行操作,不是root用户的话可能会存在权限问题,后续操作起来比较麻烦
3.2 编译环境
先安装所需要的依赖包
yum install git gcc gcc-c++ make automake autoconf libtool pcre pcre-devel zlib zlib-devel openssl-devel wget vim -y
3.3 磁盘目录
在操作之前,我先说一下我每个文件都安装到哪些地方,方便管理,同时也避免文件都已经上传成功了,结果找不着图片在虚拟机上的位置,虽然并不影响前端拿图片;
所有安装包:/usr/local/src
数据存储位置:/home/dfs/
mkdir /home/dfs #创建数据存储目录
cd /usr/local/src #切换到安装目录准备下载安装包
3.4 安装libfastcommon
git clone https://github.com/happyfish100/libfastcommon.git --depth 1
cd libfastcommon/
./make.sh && ./make.sh install #编译安装
3.5 安装FastDFS
cd ../ #返回上一级目录
git clone https://github.com/happyfish100/fastdfs.git --depth 1
cd fastdfs/
./make.sh && ./make.sh install #编译安装
#配置文件准备
cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf
cp /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf
cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf #客户端文件,测试用
cp /usr/local/src/fastdfs/conf/http.conf /etc/fdfs/ #供nginx访问使用
cp /usr/local/src/fastdfs/conf/mime.types /etc/fdfs/ #供nginx访问使用
3.6 安装fastdfs-nginx-module
cd ../ #返回上一级目录
git clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1
cp /usr/local/src/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs
3.7 安装nginx
wget http://nginx.org/download/nginx-1.15.4.tar.gz #下载nginx压缩包
tar -zxvf nginx-1.15.4.tar.gz #解压
cd nginx-1.15.4/
#添加fastdfs-nginx-module模块
./configure --add-module=/usr/local/src/fastdfs-nginx-module/src/
make && make install #编译安装
四、单机部署
我这里没有涉及到集群的操作,所以就只搞了单机部署,要做集群的小伙伴直接按官方配置文档操作就行了
4.1 tracker配置
在Xshell或者虚拟机里面改配置文件操作命令:i:修改文件;修改完后按Esc;按:(英文分号)进入编辑状态;w:保存但不退出;w!:强制保存,但不退出;wq:保存并退出;wq!:强制保存并退出;q:不保存文件退出;q!:不保存文件,强制退出;e!:放弃所有修改,从上次保存文件开始再编辑
#我自己的服务器ip为 192.168.31.36
#可以用ftp下载下来这些文件进行本地修改,当然也可以直接在终端上进行修改
vim /etc/fdfs/tracker.conf
#需要修改的内容如下
port=22122 # tracker服务器端口(默认22122,一般不修改)
base_path=/home/dfs # 存储日志和数据的根目录
4.2 storage配置
vim /etc/fdfs/storage.conf
#需要修改的内容如下
port=23000 # storage服务端口(默认23000,一般不修改)
base_path=/home/dfs # 数据和日志文件存储根目录
store_path0=/home/dfs # 第一个存储目录
tracker_server=192.168.31.36:22122 # tracker服务器IP和端口
http.server_port=8888 # http访问文件的端口(默认8888,看情况修改,和nginx中保持一致)
4.3 client测试
vim /etc/fdfs/client.conf
#需要修改的内容如下
base_path=/home/dfs
tracker_server=192.168.31.36:22122 #tracker服务器IP和端口
fdfs_upload_file /etc/fdfs/client.conf /usr/local/src/nginx-1.15.4.tar.gz
4.4 配置nginx访问
这个文件修改的东西可能会很多,小伙伴们细心一点,免得到后面出了问题不好找
vim /etc/fdfs/mod_fastdfs.conf
#需要修改的内容如下
tracker_server=192.168.31.36:22122 #tracker服务器IP和端口
url_have_group_name=true
store_path0=/home/dfs
#配置nginx.config
vim /usr/local/nginx/conf/nginx.conf
#添加如下配置
server {
listen 8888; ## 该端口为storage.conf中的http.server_port相同
server_name localhost;
location ~/group[0-9]/ {
ngx_fastdfs_module;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
到这一步环境就已经配置好了,在终端上的测试代码,文档上的,我弄的不是太明白,我就没有写在这儿,那我是怎么测试的呢,我把所有环境配好了,该启动的都启动了,然后在java代码中写的一个demo去进行测试的
五、启动
5.1 防火墙
#防火墙保持关闭,不关闭防火墙的话无法使用
systemctl stop firewalld.service #关闭
systemctl restart firewalld.service #重启
5.2 tracker
/etc/init.d/fdfs_trackerd start #启动tracker服务
/etc/init.d/fdfs_trackerd restart #重启动tracker服务
/etc/init.d/fdfs_trackerd stop #停止tracker服务
chkconfig fdfs_trackerd on #自启动tracker服务
5.3 storage
/etc/init.d/fdfs_storaged start #启动storage服务
/etc/init.d/fdfs_storaged restart #重动storage服务
/etc/init.d/fdfs_storaged stop #停止动storage服务
chkconfig fdfs_storaged on #自启动storage服务
5.4 nginx
/usr/local/nginx/sbin/nginx #启动nginx
/usr/local/nginx/sbin/nginx -s reload #重启nginx
/usr/local/nginx/sbin/nginx -s stop #停止nginx
六、测试
如果你已经把上面的每一步都操作了,并且没有报错,好的,那就已经成功了90%
我是写的一个javademo进行测试,先要去导一个fastdfs文件服务器的jar包
如果不是springboot项目的话就只有自行去下载jar包了
<dependency>
<groupId>org.csource</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.29-SNAPSHOT</version>
</dependency>
然后需要一个配置文件,这里我就新建了一个fdfs_client.conf文件
把ip和端口写进去
tracker_server=192.168.31.36:22122
fastdfs文件服务器测试代码
import org.csource.common.MyException;
import org.csource.fastdfs.*;
import java.io.IOException;
public class FastdfsDemo {
public static void main(String[] args) throws IOException, MyException {
// 1、加载配置文件,配置文件中的内容就是 tracker 服务的地址。
ClientGlobal.init("F:/es_demo/common/src/main/resources/fdfs_client.conf");
// 2、创建一个 TrackerClient 对象。直接 new 一个。
TrackerClient trackerClient = new TrackerClient();
// 3、使用 TrackerClient 对象创建连接,获得一个 TrackerServer 对象。
TrackerServer trackerServer = trackerClient.getTrackerServer();
// 4、创建一个 StorageServer 的引用,值为 null
StorageServer storageServer = null;
// 5、创建一个 StorageClient 对象,需要两个参数 TrackerServer 对象、StorageServer 的引用
StorageClient storageClient = new StorageClient(trackerServer, storageServer);
// 6、使用 StorageClient 对象上传图片。
//文件位置,后缀,扩展名,不带“.”
String[] strings = storageClient.upload_file(
"C:/Users/Mr/Desktop/个人总结/常用工具/06_images/photo8.jpg",
"jpg", null);
// 7、返回数组。包含组名和图片的路径。
for (String string : strings) {
System.out.println(string);
}
}
}
成功执行之后,会在控制打印分组和对应目录和文件名,
这样的一个东西
group1
M00/00/00/wKgfel8eqFaAHLjtAABWnR-RCJ0411.jpg