FastDFS
原理
是一个开源的轻量级分布式文件系统,对文件进行管理。
-
功能:
文件存储,文件访问,文件上传下载。 -
单次存储大小:
4k–500M -
好处:
解决了大量存储和负载均衡问题。 -
用处:
适合文件类的在线服务,比如视频网站腾讯视频,相册看图网站图虫。
二、服务端两个角色:
-
跟踪器(tracker):
做调度工作,起到负载均衡的作用。管理集群,也可以实现集群。每个tracker阶段地位平等,负责收集storage的状态。 -
存储节点(storage):
实际保存文件storage分为多个组,每个组保存的文件时不同的。
每个组有多个组成员,组成员保存的内容是一样的,组成员地位平等,没有主从概念。
三、执行流程
1.初始化连接配置
2.创建一个Tracker客户端,目的是为了连接Tracker,获取TrackerServer对象
3.通过TrackerServer创建一个Storage客户端对象,该对象用来操作Storage
4.通过Storage实现上传下载
5.获取文件上传下载信息
实践
安装环境
yum install git gcc gcc-c++ make automake autoconf libtool pcre pcre-deval zlib zlib-devel openssl-devel wget vim -y
关闭防火墙
systemctl disable firewalld
下载
git clone https://gitee.com/fastdfs100/libfastcommon.git --depth 1
cd libfastcommon
./make.sh && ./make.sh install
git clone https://gitee.com/fastdfs100/fastdfs.git --depth 1
cd fastdfs
./make.sh && ./make.sh install
git clone https://gitee.com/fastdfs100/fastdfs-nginx-module.git --depth 1
cd fastdfs-nginx-module
./make.sh && ./make.sh install
修改配置文件
mkdir -p /data/fastdfs # -p 如果存在
# 这步时创建文件夹,就是存储路径的文件,名字自己定义,要和后面的保持一致
# 对于 tracker.conf
base_path=/data/fastdfs # 路径设置,自定义路径,其中文件夹要自己创建必须存在
# 对于 storage.conf
base_path=/data/fastdfs # 存储根路径路径
store_path0=/data/fastdfs # 存储路径设置
tracker_server=172.22.45.70:22122 # 一般设置内网路径,自己通过ifconfig -a 查询内网地址,不能使127.0.0.1
# 尝试过服务器外网不行,可能我是轻量级服务器的原因
http.server_port=8989 # 设置访问端口,默认是8888,但是由于我是宝塔面板,要进行修改
# 对于client.conf 配置
tracker_server=172.22.45.70:22122
# 对于mod_fastdfs.config 这是nginx模块默认的配置文件
tracker_server=172.22.45.70:22122
store_path0=/data/fastdfs
记住复制 源文件中的 tracker.conf 、 storage.conf 、 mod_fastdfs.config (都放在)他们的 解压文件下面。复制到/etc/fdfs
# 启动
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf
# 启动storage服务
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf
# 存储图片
fdfs_upload_file /etc/fdfs/client.conf /1.JPG
#删除图片
fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/roup1/M00/00/00/rBYtRmIEre2AYPGYAABx01H1i_o128.JPG
# 停止
killall fdfs_trackerd
killall fdfs_storaged
# 查看运行情况
ps -ef|grep tracker
ps -ef|grep storage
配置ngnix
tracker_server=172.22.45.70:22122
url_have_group_name = true
store_path0=/data/fastdfs
nginx 添加模块步骤
先查看之前的安装设置项:
/www/server/nginx/sbin/nginx -V
会显示如下:(你不一定跟我版本一样,所以你显示可能会与我有所差别)
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.1.1g 21 Apr 2020
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --with-openssl=/www/server/nginx/src/openssl --with-pcre=pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --add-module=/www/server/nginx/src/nginx-dav-ext-module
其中我是使用宝塔面板的,所以按照nginx需要编译安装,自己配置其中的文件路径,添加模块,建议按照1.16版本
注意把 configure arguments: 后面的配置项复制一下,例如我这把下面的内容都复制下来了
--user=www --group=www --prefix=/www/server/nginx --add-module=srclib/ngx_devel_kit --add-module=srclib/lua_nginx_module --add-module=srclib/ngx_cache_purge --add-module=srclib/nginx-sticky-module --with-openssl=srclib/openssl --with-pcre=srclib/pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-http_dav_module --add-module=srclib/nginx-dav-ext-module
切换到你的宝塔安装目录,输入如下命令
cd /www/server/nginx/src
现在把你要安装的模块添加进去(例如我要添加的是fastdfs-nginx-module
这个模块),你仔细看我下面的命令已经在最后面加了一个--add-module=/usr/local/fastdfs-nginx-module/src
./configure --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --with-openssl=/www/server/nginx/src/openssl --with-pcre=pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --add-module=/www/server/nginx/src/nginx-dav-ext-module --add-module=/usr/local/fastdfs-nginx-module/src/
执行完上面的命令之后make一下
make
安装 重新安装
make install
注意,此时你看它会自动给你备份了原来安装的,有个***.old文件,而且你本次安装原来的配置不会失效
ll /www/server/nginx/sbin
重启nginx
/www/server/nginx/sbin/nginx -s stop #注意,这是停止
/www/server/nginx/sbin/nginx #注意,这是启动,不带任何参数的
/www/server/nginx/sbin/nginx reload # 重启
ok,大功告成,如果你不是宝塔安装的nginx,也可以以此类推解决,关键是要找到nginx的configure,修改里面的设置项,再make就行了
nginx 配置文件
server { listen 8989; server_name localhost; location ~/group[0-9]/ { ngx_fastdfs_module; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; }}
访问 记住文件名字一定准确
wget http://172.22.45.70:8989/group1/M00/00/00/rBYtRmIEre2AYPGYAABx01H1i_o128.JPG
使用宝塔面板的网站反向代理进行网页访问
大坑
- 由于我是使用了宝塔面试,占用了我的8888端口,记得在storage上把端口改成其他端口,同理在nginx上也要修改
整合Java
导入包
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
配置文件
fastdfs.connect_timeout_in_seconds=10
fastdfs.network_timeout_in_seconds=30
fastdfs.charset=UTF-8
fastdfs.tracker_servers=120.24.43.3:22122
fastdfs.http_tracker_http_port=8989
工具类
package com.peng.utils;
import com.peng.Test;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import java.util.Properties;
/**
* @description:
* @projectName: FastDFS
* @see: com.peng.utils
* @author: pc
* @createTime: 2022/2/10 17:50
* @version: 1.0
*/
public class FastDFSUtils {
private FastDFSUtils() {}
private static final Properties properties = new Properties();
private static final StorageClient storageClient;
static {
try {
Properties properties = new Properties();
properties.load(Test.class.getClassLoader().getResourceAsStream("fdfs.properties"));
ClientGlobal.initByProperties(properties);
// 使用的就是配置文件的地址生成的客服端
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getConnection();
StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
storageClient = new StorageClient(trackerServer, storageServer);
} catch (Exception e) {
e.printStackTrace();
// 初始化代码块异常,抛出错误,停止虚拟机
throw new ExceptionInInitializerError(e);
}
}
/**
* @desc 删除文件
* @param group
* @param path
* @return boolean
* @author pengshi
* @date 2022/2/10 18:29
**/
public static boolean delete(String group, String path) {
try {
int stat = storageClient.delete_file(group, path);
return stat == 0;
} catch (Exception e) {
e.printStackTrace();
// 删除失败
return false;
}
}
/**
* @desc 下载文件
* @param group 组名
* @param path 文件路径以及文件名字
* @return byte文件二进制数据
* @author pengshi
* @date 2022/2/10 18:18
**/
public static byte[] download(String group, String path) {
try {
return storageClient.download_file(group, path);
} catch (Exception e) {
e.printStackTrace();
// 下载失败
return null;
}
}
/**
* @desc 根据组名和文件信息查询元数据数组
* @param group 组名
* @param path 文件路径以及文件名字
* @return NameValuePair
* @author pengshi
* @date 2022/2/10 18:21
**/
public static NameValuePair[] getMetaData(String group, String path) {
try {
return storageClient.get_metadata(group, path);
}catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* @desc 上传文件数据
* @param data
* @param extName
* @param nvps
* @return String 文件路径
* @author pengshi
* @date 2022/2/10 18:17
**/
public static String uploadFile(byte[] data, String extName, NameValuePair[] nvps) {
try {
String[] result = storageClient.upload_file(data, extName, nvps);
String path = result[0] + "/" + result[1];
return path;
} catch (Exception e) {
e.printStackTrace();
// 上传失败
return null;
}
}
}