Java高级架构之FastDFS分布式文件集群
本文是第一篇!
第二篇,《SpringBoot集成FastDFS+Nginx整合基于Token的防盗链》https://blog.51cto.com/xvjunjie/2381361
第三篇,《FastDFS的HA架构多Group多Storage多Tracker结合SpringBoot》https://blog.51cto.com/xvjunjie/2445770
FastDFS是一款开源的轻量级分布式文件系统,使用C实现,支持Linux、BSD等unix-like操作系统。值得注意的是,fastdfs并不是通用的文件系统,只能通过专用的API访问。
fastdfs为互联网应用量身定做,解决了大容量文件存储的问题,fastdfs追求高性能和高扩展性。fastdfs的主要概念:
tracker-server:跟踪服务器。用于跟踪文件,主要起调度作用。在内存中记录了所有存储组和存储服务器的状态信息,是客户端和数据存储的主要枢纽。相比GFS更为精简,因为不记录文件索引。
storage-server: 存储服务器。用于存储文件。直接使用操作系统的文件系统来管理和组织文件。
group: 组,卷。多个服务器存在一个组中,在一个组中的服务器存储的文件是完全相同的,并且同一个组的服务器地位是对等的。对于文件的操作可以在任意一个组中的服务器上进行。
metadata: 元数据。以键值对的方式存储,用于存储文件的相关信息。各大存储系统的对比话说没有对比就没有伤害,fastdfs也不是万能的,需要根据业务来选择适合的存储系统。
mkdir /sourcecd /sourceyum install -y gcc gcc-c++ make cmake wget libeventwget https://github.com/happyfish200/libfastcommon/archive/V1.0.35.tar.gzwget https://github.com/happyfish200/fastdfs/archive/V5.10.tar.gztar -zxvf V1.0.35.tar.gztar -zxvf V5.10.tar.gzcd libfastcommon-1.0.35./make.sh./make.sh installln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.socd ../cd fastdfs-5.10/./make.sh./make.sh installcd ../cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.confcp /etc/fdfs/storage.conf.sample /etc/fdfs/storage.confcp /etc/fdfs/client.conf.sample /etc/fdfs/client.confmkdir -p /data/fdfs/trackermkdir -p /data/fdfs/storagemkdir -p /data/fdfs/clientln -s /usr/bin/stop.sh /usr/local/bin/stop.shln -s /usr/bin/restart.sh /usr/local/bin/restart.sh
修改配置文件
修改跟踪器配置文件:
base_path=/data/fdfs/tracker
修改存储器配置文件:
base_path=/data/fdfs/storagestore_path0=/data/fdfs/storagetracker_server=192.168.80.3:22122
修改客户端配置文件:
base_path=/data/fdfs/clienttracker_server=192.168.80.3:22122
启动
/etc/init.d/fdfs_trackerd start/etc/init.d/fdfs_storaged start
netstat -tunlap | grep :22122tcp 0 0 0.0.0.0:22122 0.0.0.0:* LISTEN 7247/fdfs_trackerd tcp 0 0 192.168.80.3:22122 192.168.80.3:39318 ESTABLISHED 7247/fdfs_trackerd tcp 0 0 192.168.80.3:39318 192.168.80.3:22122 ESTABLISHED 7444/fdfs_storaged
启动后要查看状态, 出现 active (exited)
字样可以尝试重启服务。
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf /source/FastDFS_v5.05.tar.gzgroup1/M00/00/00/wKhQA1ysjSGAPjXbAAVFOL7FJU4.tar.gz
文件存储在:
ll /data/fdfs/storage/data/00/00/wKhQA1ysjSGAPjXbAAVFOL7FJU4.tar.gz
安装Nginx并配置模块
# 安装Nginx需要的pcre(Perl兼容正则表达式)库,允许Nginx使用rewrite模块提供URL重写功能。yum install pcre pcre-devel perl-ExtUtils-Embed -y# 安装openssl-devel,允许Nginx提供HTTPS服务。yum install openssl-devel -y# 下载软件包cd /sourcewget http://59.80.44.46/nginx.org/download/nginx-1.14.2.tar.gzwget http://nchc.dl.sourceforge.net/project/fastdfs/FastDFS%20Nginx%20Module%20Source%20Code/fastdfs-nginx-module_v1.16.tar.gz# 解压软件包tar xvf nginx-1.14.2.tar.gztar xvf fastdfs-nginx-module_v1.16.tar.gz# 创建必要的软连接ln -s /usr/include/fastdfs/ /usr/local/include/fastdfsln -s /usr/include/fastcommon/ /usr/local/include/fastcommoncp fastdfs-5.10/conf/http.conf /etc/fdfs/cp fastdfs-5.10/conf/mime.types /etc/fdfs/cp fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/mkdir -p /data/fdfs/fastdfs-nginx-module
修改配置文件 /etc/fdfs/mod_fastdfs.conf
:
connect_timeout=10base_path=/data/fdfs/fastdfs-nginx-module# 配置服务器的地址tracker_server=192.168.80.3:22122url_have_group_name = truestore_path0=/data/fdfs/storage
mkdir /applicationsmkdir /tmp/nginxuseradd nginx -s /sbin/nologin -Mcd nginx-1.14.2./configure \--user=nginx \--group=nginx \--prefix=/applications/nginx-1.14.2 \--with-http_ssl_module \--with-http_gzip_static_module \--http-client-body-temp-path=/tmp/nginx/client \--http-proxy-temp-path=/tmp/nginx/proxy \--http-fastcgi-temp-path=/tmp/nginx/cgi \--with-poll_module \--with-file-aio \--with-http_realip_module \--with-http_addition_module \--with-http_random_index_module \--with-pcre \--with-http_stub_status_module \--with-stream \--add-module=/source/fastdfs-nginx-module/srcmakemake installln -s /applications/nginx-1.14.2/ /applications/nginxchown -R nginx.nginx /applications/nginxchown -R nginx.nginx /applications/nginx-1.14.2/chown -R nginx.nginx /tmp/nginx/
修改配置文件 /applications/nginx/conf/nginx.conf
, 在http区块添加:
server { listen 8000; server_name media; location / { root html; index index.html index.htm; } # 拦截文件请求,转发到下面的模块 location ~/group[0-9] { ngx_fastdfs_module; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
测试配置文件正确性并启动:
/applications/nginx/sbin/nginx -t/applications/nginx/sbin/nginx
删除临时文件:
rm -rf fastdfs-5.10rm -rf fastdfs-nginx-modulerm -rf libfastcommon-1.0.35rm -rf nginx-1.14.2
测试Nginx文件下载功能, 在浏览器输入: http://192.168.80.3:8000/group1/M00/00/00/wKhQA1ysjSGAPjXbAAVFOL7FJU4.tar.gz
一个nginx只能访问一个storage服务器的数据,所以多个storage服务器要配置多个nginx,然后将nginx按照请求路径中的组id(groupid)进行路由。
简单的启动停止服务的脚本:
# start-service# usage: ./start-serviceecho "============================================Sync datetime==========================================="ntpdate time7.aliyun.comecho "===========================================Getting status==========================================="/etc/init.d/fdfs_trackerd status/etc/init.d/fdfs_storaged statusecho "==========================================Starting service=========================================="/etc/init.d/fdfs_storaged start/etc/init.d/fdfs_trackerd startecho "===========================================Getting status==========================================="/etc/init.d/fdfs_trackerd status/etc/init.d/fdfs_storaged statusecho "=========================================Testing config file========================================"/applications/nginx/sbin/nginx -techo "=========================================Starting web server========================================"/applications/nginx/sbin/nginxecho "=======================================Getting network status======================================="sleep 5snetstat -tunlap | grep :22122netstat -tunlap | grep :8000
# stop-service# usage: ./stop-serviceecho "===========================================Getting status==========================================="/etc/init.d/fdfs_trackerd status/etc/init.d/fdfs_storaged statusecho "==========================================Stopping service=========================================="/etc/init.d/fdfs_storaged stop/etc/init.d/fdfs_trackerd stopecho "========================================Stopping web server========================================="kill `cat /applications/nginx/logs/nginx.pid`echo "===========================================Getting status==========================================="/etc/init.d/fdfs_trackerd status/etc/init.d/fdfs_storaged statusecho "=======================================Getting network status======================================="sleep 5snetstat -tunlap | grep :22122netstat -tunlap | grep :8000
基于Token的防盗链实现
FastDFS内置使用Token的方式实现防盗链,Token是带有时效性的,Token中包含了文件id、时间戳ts和token。在FastDFS中使用URL带上ts和token的方式请求资源。在FastDFS中提供了生成Token的算法,扩展模块会对Token进行验证。由于Token的生成和校验都在服务器端,因此不会存在安全性问题。链接示例:
http://192.168.1.15:8080/group1/M01/01/01/wKgBD01c15nvKU1cAABAOeCdFS466570.c?token=b32cd06a53dea4376e43d71cc882f9cb&ts=1297930137
在 /etc/fdfs/http.conf
中修改:
# 开启Token校验http.anti_steal.check_token=true# Token的声明周期为240秒http.anti_steal.token_ttl=240# 加密字符串,可以使用 openssl rand -base64 64 生成http.anti_steal.secret_key=2scPwMPctXhbLVOYB0jyuyQzytOofmFCBIYe65n56PPYVWrntxzLIDbPdvDDLJM8QHhKxSGWTcr+9VdG3yptkw# Token校验失败的时候返回的图片 http.anti_steal.token_check_fail=/data/fdfs/error.svg
使用Java客户端验证:
将客户端安装到本地仓库:
git clone https://github.com/happyfish200/fastdfs-client-java.gitcd fastdfs-client-javamvn clean install
使用Maven创建一个普通的项目,在POM文件中添加依赖:
<dependencies> <dependency> <groupId>org.csource</groupId> <artifactId>fastdfs-client-java</artifactId> <version>1.27-SNAPSHOT</version> </dependency></dependencies>
在resources目录下创建FastDFS配置文件 fastdfs-client.properties
:
fastdfs.connect_timeout_in_seconds = 5fastdfs.network_timeout_in_seconds = 30fastdfs.charset = UTF-8fastdfs.http_anti_steal_token = truefastdfs.http_secret_key = 2scPwMPctXhbLVOYB0jyuyQzytOofmFCBIYe65n56PPYVWrntxzLIDbPdvDDLJM8QHhKxSGWTcr+9VdG3yptkwfastdfs.http_tracker_http_port = 8080fastdfs.tracker_servers = 192.168.80.3:22122
创建 com.bluemiaomiao.Demo.java
类文件:
package com.bluemiaomiao;import org.csource.common.MyException;import org.csource.fastdfs.ClientGlobal;import org.csource.fastdfs.ProtoCommon;import java.io.IOException;import java.security.NoSuchAlgorithmException;import java.util.Properties;public class Demo { public static void main(String[] args) throws IOException, MyException, NoSuchAlgorithmException { // 加载配置文件 Properties prop = new Properties(); prop.load(Demo.class.getResourceAsStream("/fastdfs-client.properties")); ClientGlobal.initByProperties(prop); // 显示初始化配置信息 System.out.println(ClientGlobal.configInfo()); // 使用文件上传工具返回的地址,一般情况下保存在数据库中 String remoteFileName = "group1/M00/00/00/wKhQA1ysjSGAPjXbAAVFOL7FJU4.tar.gz"; // 获取当前时间戳 int ts = (int)(System.currentTimeMillis()/1000); // 获取Token, 传入的文件ID不要含有分组信息 String token = ProtoCommon.getToken("M00/00/00/wKhQA1ysjSGAPjXbAAVFOL7FJU4.tar.gz", ts, prop.getProperty("fastdfs.http_secret_key")); // 使用浏览器访问返回的URL System.out.println("http://192.168.80.3:8000/" + remoteFileName + "?token=" + token + "&ts=" + ts); }}
如果访问时显示防盗链图片,可能是测试客户端与服务器之间的之间有一定差距,两个主机之间不能有分钟级别的差距,可以使用如下方法同步服务器:
# 安装同步时间服务器的客户端, Windows系统也需要与该服务器同步# 控制面板->时钟和区域->设置日期和时间->Internet时间->更改设置yum install ntpdatentpdate time7.aliyun.com
整合FastDHT实现数据去重
FastDHT是分布式哈希系统(DHT),使用BerkeleyDB做数据存储,使用libevent做网络IO处理。依赖于libfastcommon组件。
下载去Oracle官方网站下载 Berkeley DB 数据库,去Fastdfs的GitHub主页下载FastDHT的源码包。由于之前已经安装过linevent和libfastcommon,因此只需要安装数据库和FastDHT即可。
安装配置数据库与FastDHTtar -xvf db-6.2.23.tar.gzcd db-6.2.23/build_unix/../dist/configure --prefix=/applications/db-6.2.23make -jmake installecho '/applications/db-6.2.23/lib/' >> /etc/ld.so.confldconfigcd ../../rm -rf db-6.2.23unzip fastdht-master.zipcd fastdht-mastervim make.sh
修改第27行代码:
CFLAGS='-Wall -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I /applications/db-6.2.23/include/ -L /applications/db-6.2.23/lib/'
-I
: 指定数据库提供的头文件目录
-L
: 指定数据库提供的库文件目录
./make.sh./make.sh installcd ../rm -rf fastdht-master
配置
mkdir /data/fdht
修改 /etc/fdht/fdht_client.conf
内容:
base_path=/data/fdht#include /etc/fdht/fdht_servers.conf
修改 /etc/fdht/fdht_servers.conf
内容:
group0 = 192.168.80.3:11411
修改 /etc/fdht/fdhtd.conf
内容:
base_path=/data/fdht#include /etc/fdht/fdht_servers.conf
修改 /etc/fdfs/storage.conf
内容:
check_file_duplicate=1key_namespace=FastDFSkeep_alive=1#include /etc/fdht/fdht_servers.conf
主要需要包含服务器端配置文件。
ln -s /applications/db-6.2.23/lib/libdb-6.2.so /usr/lib/libdb-6.2.soln -s /applications/db-6.2.23/lib/libdb-6.2.so /usr/lib64/libdb-6.2.so
启动并测试
fdhtd /etc/fdht/fdhtd.conf
重启使用:
fdhtd /etc/fdht/fdhtd.conf restart
查看结果:
netstat -tunlap | grep :11411tcp 0 0 0.0.0.0:11411 0.0.0.0:* LISTEN 20605/fdhtd
由于安装FastDHT的时候关闭了FastDFS,因此需要启动FastDFS
./start-service
修改之前的 start-service
脚本, 在启动tracker和storage服务之前添加:
fdhtd /etc/fdht/fdhtd.conf
在查看tracker和ngixn网络状态之前添加:
netstat -tunlap | grep :11411
测试:
fdfs_upload_file /etc/fdfs/client.conf /source/db-6.2.23.tar.gzgroup1/M00/00/00/wKhQA1yu2L6APTk-AqQOLABfhaQ.tar.gzfdfs_upload_file /etc/fdfs/client.conf /source/db-6.2.23.tar.gzgroup1/M00/00/00/wKhQA1yu2MKAOmIiAqQOLHUWXfw.tar.gzll /data/fdfs/storage/data/00/00/total 45268-rw-r--r-- 1 root root 44305964 Apr 11 14:03 wKhQA1yu2L6AM0aiAqQOLKFBFuc.tar.gzlrwxrwxrwx 1 root root 64 Apr 11 14:03 wKhQA1yu2L6APTk-AqQOLABfhaQ.tar.gz -> /data/fdfs/storage/data/00/00/wKhQA1yu2L6AM0aiAqQOLKFBFuc.tar.gzlrwxrwxrwx 1 root root 64 Apr 11 14:03 wKhQA1yu2MKAOmIiAqQOLHUWXfw.tar.gz -> /data/fdfs/storage/data/00/00/wKhQA1yu2L6AM0aiAqQOLKFBFuc.tar.gz
自定义 fastdfs-spring-boot-starter
为了快速构建SpringBoot项目,我们可以自定义一个场景启动器来解决。详细信息:https://github.com/bluemiaomiao/fastdfs-spring-boot-starter .
下面使用SpringBoot构建一个示例项目:
添加依赖:<dependency> <groupId>com.bluemiaomiao</groupId> <artifactId>fastdfs-spring-boot-starter</artifactId> <version>1.0-SNAPSHOT</version></dependency>
在主配置类中添加注解:
@EnableFastdfsClient@SpringBootApplicationpublic class DemoApplication {@Autowiredprivate FastdfsClientService fastdfsClientService;public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args);}}
此时将会自动初始化好全局客户端。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。