FastDFS安装并 spring 集成(包含 Nginx)
来源:互联网 发布:五毛钱特效软件 编辑:程序博客网 时间:2024/06/03 12:28
第一次写博客,不好之处请见谅
直入主题:
FastDFS 分布式文件系统的安装与使用(单节点)
服务器地址
跟踪服务器:120.77.41.37
存储服务器:120.77.41.37
服务器环境
环境:CentOS 7
用户: root
数据目录:/fastdfs (注:数据目录按你的数据盘挂载路径而定)
安装包
FastDFS v5.05
libfastcommon-master.zip(是从 FastDFS 和 FastDHT 中提取出来的公共 C 函数库)
fastdfs-nginx-module_v1.16.tar.gz
nginx-1.6.2.tar.gz
fastdfs_client_java._v1.25.tar.gz
源码地址:https://github.com/happyfish100/
下载地址:http://sourceforge.net/projects/fastdfs/files/
官方论坛:http://bbs.chinaunix.net/forum-240-1.html
所有跟踪服务器和存储服务器均执行如下操作:
编译和安装所需的依赖包:
# yum install make cmake gcc gcc-c++
安装 libfastcommon:
- 上传或下载 libfastcommon-master.zip 到/usr/local/src 目录
- 解压:
# cd /usr/local/src/
# unzip libfastcommon-master.zip
# cd libfastcommon-master
- 编译、安装:
# ./make.sh
# ./make.sh install
libfastcommon 默认安装到了
/usr/lib64/libfastcommon.so
/usr/lib64/libfdfsclient.so
- 因为 FastDFS 主程序设置的 lib 目录是/usr/local/lib,所以需要创建软链接:
# ln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so
# ln -s /usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so
# ln -s /usr/lib64/libfdfsclient.so /usr/local/lib/libfdfsclient.so
# ln -s /usr/lib64/libfdfsclient.so /usr/lib/libfdfsclient.so
安装 FastDFS
- 上传或下载 FastDFS 源码包(FastDFS_v5.05.tar.gz)到 /usr/local/src 目录
- 解压:
# cd /usr/local/src/
# tar -zxvf FastDFS_v5.05.tar.gz
# cd FastDFS
- 编译、安装(编译前要确保已经成功安装了 libfastcommon)
# ./make.sh
# ./make.sh install
采用默认安装的方式安装,安装后的相应文件与目录:
A、服务脚本在:
/etc/init.d/fdfs_storaged
/etc/init.d/fdfs_tracker
B、配置文件在(样例配置文件):
/etc/fdfs/client.conf.sample
/etc/fdfs/storage.conf.sample
/etc/fdfs/tracker.conf.sample
C、命令工具在/usr/bin/目录下的:
fdfs_appender_test
fdfs_appender_test1
fdfs_append_file
fdfs_crc32
……
- 因为 FastDFS 服务脚本设置的 bin 目录是/usr/local/bin,但实际命令安装在/usr/bin,可以进入 /user/bin 目录使用以下命令查看 fdfs 的相关命令:
# cd /usr/bin/
# ls | grep fdfs
- 因此需要修改 FastDFS 服务脚本中相应的命令路径,也就是把/etc/init.d/fdfs_storaged 和/etc/init.d/fdfs_tracker 两个脚本中的/usr/local/bin 修改成/usr/bin:
# vi fdfs_trackerd
- 使用查找替换命令进统一修改:%s+/usr/local/bin+/usr/bin
# vi fdfs_storaged
- 使用查找替换命令进统一修改:%s+/usr/local/bin+/usr/bin
配置 FastDFS 跟踪器
复制 FastDFS 跟踪器样例配置文件,并重命名:
# cd /etc/fdfs/
# cp tracker.conf.sample tracker.conf
编辑跟踪器配置文件:
# vi /etc/fdfs/tracker.conf
修改的内容如下:
disabled=false
port=22122
base_path=/fastdfs/tracker
(其它参数保留默认配置,具体配置解释请参考官方文档说明: http://bbs.chinaunix.net/thread-1941456-1-1.html )
创建基础数据目录(参考基础目录 base_path 配置):
# mkdir -p /fastdfs/tracker
防火墙中打开跟踪器端口(默认为 22122):
# vi /etc/sysconfig/iptables
添加如下端口行:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22122 -j ACCEPT
重启防火墙:
# service iptables restart
启动 Tracker:
# /etc/init.d/fdfs_trackerd star
(初次成功启动,会在/fastdfs/tracker 目录下创建 data、logs 两个目录)
查看 FastDFS Tracker 是否已成功启动:
# ps -ef | grep fdfs
关闭 Tracker:
# /etc/init.d/fdfs_trackerd stop
设置 FastDFS 跟踪器开机启动:
# vi /etc/rc.d/rc.local
添加以下内容:
## FastDFS Tracker
/etc/init.d/fdfs_trackerd start
配置 FastDFS 存储
复制 FastDFS 存储器样例配置文件,并重命名:
# cd /etc/fdfs/
# cp storage.conf.sample storage.conf
编辑存储器样例配置文件:
# vi /etc/fdfs/storage.conf
修改的内容如下:
disabled=false
port=23000
base_path=/fastdfs/storage
store_path0=/fastdfs/storage
tracker_server=120.77.41.37:22122
http.server_port=8888
(其它参数保留默认配置,具体配置解释请参考官方文档说明: http://bbs.chinaunix.net/thread-1941456-1-1.html )
创建基础数据目录(参考基础目录 base_path 配置):
# mkdir -p /fastdfs/storage
防火墙中打开存储器端口(默认为 23000):
参考上面修改防火墙
启动 Storage:
# /etc/init.d/fdfs_storaged start
初次成功启动,会在/fastdfs/storage 目录下创建 data、logs 两个目录)
关闭 Storage:
# /etc/init.d/fdfs_storaged stop
设置 FastDFS 存储器开机启动:
# vi /etc/rc.d/rc.local
添加:
## FastDFS Storage
/etc/init.d/fdfs_storaged start
四、文件上传测试
修改 Tracker 服务器中的客户端配置文件:
# cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf
# vi /etc/fdfs/client.conf
修改内容如下:
base_path=/fastdfs/tracker
btracker_server=120.77.41.37:22122
执行如下文件上传命令:
# /usr/bin/fdfs_upload_file /etc/fdfs/client.conf /usr/local/src/FastDFS_v5.05.tar.gz
返回 ID 号:group1/M00/00/00/wKFHOASIOCO43242342XO.tar.gz
能返回以上文件 ID,说明文件上传成功)
在每个存储节点上安装 nginx
fastdfs-nginx-module 作用说明:
FastDFS 通过 Tracker 服务器,将文件放在 Storage 服务器存储,但是同组存储服务器之间需要进入文件复制,有同步延迟的问题。假设 Tracker 服务器将文件上传到了 120.77.41.37,上传成功后文件 ID 已经返回给客户端。此时 FastDFS 存储集群机制会将这个文件同步到同组存储 120.77.41.37,在文件还 没有复制完成的情况下,客户端如果用这个文件 ID 在 120.77.41.37 上取文件,就会出现文件无法访问的 错误。而 fastdfs-nginx-module 可以重定向文件连接到源服务器取文件,避免客户端由于复制延迟导致的 文件无法访问错误。(解压后的 fastdfs-nginx-module 在 nginx 安装时使用)
上传 fastdfs-nginx-module_v1.16.tar.gz 到/usr/local/src
解压
# cd /usr/local/src/
# tar -zxvf fastdfs-nginx-module_v1.16.tar.gz
修改 fastdfs-nginx-module 的 config 配置文件:
# cd fastdfs-nginx-module/src
# vi config
CORE_INCS=”$CORE_INCS /usr/local/include/fastdfs /usr/local/include/fastcommon/”
修改为:
CORE_INCS=”$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/”
注意:这个路径修改是很重要的,不然在 nginx 编译的时候会报错的)
上传当前的稳定版本 Nginx(nginx-1.6.2.tar.gz)到/usr/local/src 目录:
安装编译 Nginx 所需的依赖包:
# yum install gcc gcc-c++ make automake autoconf libtool pcre* zlib openssl openssl-devel
编译安装 Nginx(添加 fastdfs-nginx-module 模块):
# cd /usr/local/src/
# tar -zxvf nginx-1.6.2.tar.gz
# cd nginx-1.6.2
# ./configure –add-module=/usr/local/src/fastdfs-nginx-module/src
# make && make install
复制 fastdfs-nginx-module 源码中的配置文件到/etc/fdfs 目录,并修改:
# cp /usr/local/src/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/
# vi /etc/fdfs/mod_fastdfs.conf
修改以下配置:
connect_timeout=10
base_path=/tmp
tracker_server=120.77.41.37:22122
storage_server_port=23000
group_name=group1
url_have_group_name = true
store_path0=/fastdfs/storage
复制 FastDFS 的部分配置文件到/etc/fdfs 目录:
# cd /usr/local/src/FastDFS/conf
# cp http.conf mime.types /etc/fdfs/
在/fastdfs/storage 文件存储目录下创建软连接,将其链接到实际存放数据的目录:
# ln -s /fastdfs/storage/data/ /fastdfs/storage/data/M00
配置 Nginx:
简洁版 nginx 配置样例:
user root;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 8888;
server_name localhost;
location ~/group([0-9])/M00 {
#alias /fastdfs/storage/data;
ngx_fastdfs_module;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html; }
} }
A、8888 端口值是要与/etc/fdfs/storage.conf 中的 http.server_port=8888 相对应,因为 http.server_port 默认为 8888,如果想改成 80,则要对应修改过来。B、Storage 对应有多个 group 的情况下,访问路径带 group 名,如/group1/M00/00/00/xxx,
对应的 Nginx 配置为:
location ~/group([0-9])/M00 {
ngx_fastdfs_module;
}
C、如查下载时如发现老报 404,将 nginx.conf 第一行 user nobody 修改为 user root 后重新启动。
防火墙中打开 Nginx 的 8888 端口
参考前边修改防火墙端口
启动 Nginx:
# /usr/local/nginx/sbin/nginx
ngx_http_fastdfs_set pid=xxx
(重启 Nginx 的命令为:/usr/local/nginx/sbin/nginx -s reload)
通过浏览器访问测试时上传的文件:
http://120.77.41.37:8888/group1/M00/00/00/rBIvKFll_-iAKwK9AAIpzOP593E159.jpg?token=f42b765ca5101374e831b123ce4f8fbe&ts=1499856871
浏览器成功访问
FastDFS与 Spring 整合
xml配置文件:
<bean id="fastDFSFactory" class="com.anniweiya.fastdfs.FastDFSTemplateFactory" init-method="init"> <!--连接超时的时限,单位为秒--> <property name="g_connect_timeout" value="60"/> <!--网络超时的时限,单位为秒--> <property name="g_network_timeout" value="80"/> <!--防盗链配置--> <property name="g_anti_steal_token" value="true"/> <property name="g_secret_key" value="FastDFS1234567890"/> <property name="poolConfig"> <bean class="com.anniweiya.fastdfs.pool.PoolConfig"> <!--池的大小--> <property name="maxTotal" value="100"/> <!--连接池中最大空闲的连接数--> <property name="maxIdle" value="10"/> </bean> </property> <!--tracker的配置 ","逗号分隔--> <property name="tracker_servers" value="120.77.41.37:22122"/> <!--HTTP访问服务的端口号--> <property name="g_tracker_http_port" value="8080"/> <!--nginx的对外访问地址,如果没有端口号,将取g_tracker_http_port配置的端口号 ","逗号分隔--> <property name="nginx_address" value="120.77.41.37:8888"/> </bean> <!--注入模板类--> <bean id="fastDFSTemplate" class="com.anniweiya.fastdfs.FastDFSTemplate"> <constructor-arg ref="fastDFSFactory"/> </bean>
fastDFS自定义异常处理
/** * * @Description: 文件上传异常 * @author: Aaron * @date: 2017年7月12日 下午6:56:09 */public class FastDFSException extends Exception { // serialVersionUID : TODO private static final long serialVersionUID = 1L; @SuppressWarnings("unused") //错误编码 private int errorCode = 0; public FastDFSException(int errorCode) { this.errorCode = errorCode; } public FastDFSException(String message, int errorCode) { super(message); this.errorCode = errorCode; } public FastDFSException(String message, Throwable cause, int errorCode) { super(message, cause); this.errorCode = errorCode; } public FastDFSException(Throwable cause, int errorCode) { super(cause); this.errorCode = errorCode; } public FastDFSException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, int errorCode) { super(message, cause, enableSuppression, writableStackTrace); this.errorCode = errorCode; }}
使用连接池创建连接
/** * * @Description: 使用连接池创建连接 * @author: Aaron * @date: 2017年7月12日 下午6:57:05 */class ConnectionFactory extends BasePooledObjectFactory<StorageClient> { private FastDFSTemplateFactory factory; public ConnectionFactory(FastDFSTemplateFactory templateFactory) { this.factory = templateFactory; } @Override public StorageClient create() throws Exception { TrackerClient trackerClient = new TrackerClient(factory.getG_tracker_group()); TrackerServer trackerServer = trackerClient.getConnection(); return new StorageClient(trackerServer, null); } @Override public PooledObject<StorageClient> wrap(StorageClient storageClient) { return new DefaultPooledObject<>(storageClient); } public PooledObject<StorageClient> makeObject() throws Exception { return wrap(create()); } public void destroyObject(StorageClient obj) throws Exception { close(obj.getTrackerServer()); } private void close(Closeable closeable) { if (closeable != null) { try { closeable.close(); } catch (IOException ignored) { } } }}
连接池工厂
/** * * @Description: 连接池工厂 * @author: Aaron * @date: 2017年7月12日 下午6:58:09 */public class ConnectionPoolFactory { private GenericObjectPool<StorageClient> pool; public ConnectionPoolFactory(FastDFSTemplateFactory fastDFSTemplateFactory) { pool = new GenericObjectPool<>(new ConnectionFactory(fastDFSTemplateFactory)); } public StorageClient getClient() throws Exception { return pool.borrowObject(); } public void releaseConnection(StorageClient client) { try { pool.returnObject(client); } catch (Exception ignored) { } } /** * * @Description: 修改属性 * @param poolConfig * @author: Aaron * @date: 2017年7月12日 下午6:59:02 */ @SuppressWarnings("unused") private void toConfig(PoolConfig poolConfig) { pool.setMaxTotal(poolConfig.maxTotal); pool.setMaxIdle(poolConfig.maxIdle); pool.setMinIdle(poolConfig.minIdle); pool.setTestOnBorrow(poolConfig.testOnBorrow); pool.setMaxWaitMillis(poolConfig.maxWait); }}
连接池配置类
/** * * @Description: 连接池配置 * @author: Aaron * @date: 2017年7月12日 下午7:00:07 */public class PoolConfig { public int maxIdle = 10; public int minIdle = 0; public int maxTotal = 10; public long maxWait = -1L; public boolean testOnBorrow = false; public byte whenExhaustedAction = 1; public boolean testOnReturn = false; public boolean testWhileIdle = false; public long timeBetweenEvictionRunsMillis = -1L; public int numTestsPerEvictionRun = 3; public long minEvictableIdleTimeMillis = 1800000L; public long softMinEvictableIdleTimeMillis = -1L; public boolean lifo = true; public PoolConfig() { } public int getMaxIdle() { return maxIdle; } public void setMaxIdle(int maxIdle) { this.maxIdle = maxIdle; } public int getMinIdle() { return minIdle; } public void setMinIdle(int minIdle) { this.minIdle = minIdle; } public int getMaxTotal() { return maxTotal; } public void setMaxTotal(int maxTotal) { this.maxTotal = maxTotal; } public long getMaxWait() { return maxWait; } public void setMaxWait(long maxWait) { this.maxWait = maxWait; } public byte getWhenExhaustedAction() { return whenExhaustedAction; } public void setWhenExhaustedAction(byte whenExhaustedAction) { this.whenExhaustedAction = whenExhaustedAction; } public boolean isTestOnBorrow() { return testOnBorrow; } public void setTestOnBorrow(boolean testOnBorrow) { this.testOnBorrow = testOnBorrow; } public boolean isTestOnReturn() { return testOnReturn; } public void setTestOnReturn(boolean testOnReturn) { this.testOnReturn = testOnReturn; } public boolean isTestWhileIdle() { return testWhileIdle; } public void setTestWhileIdle(boolean testWhileIdle) { this.testWhileIdle = testWhileIdle; } public long getTimeBetweenEvictionRunsMillis() { return timeBetweenEvictionRunsMillis; } public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) { this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; } public int getNumTestsPerEvictionRun() { return numTestsPerEvictionRun; } public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) { this.numTestsPerEvictionRun = numTestsPerEvictionRun; } public long getMinEvictableIdleTimeMillis() { return minEvictableIdleTimeMillis; } public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) { this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; } public long getSoftMinEvictableIdleTimeMillis() { return softMinEvictableIdleTimeMillis; } public void setSoftMinEvictableIdleTimeMillis(long softMinEvictableIdleTimeMillis) { this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis; } public boolean isLifo() { return lifo; } public void setLifo(boolean lifo) { this.lifo = lifo; }}
文件信息描述
/** * * @Description: 文件信息描述 * @author: Aaron * @date: 2017年7月12日 下午7:00:32 */public class FastDfsInfo implements java.io.Serializable { // serialVersionUID : TODO private static final long serialVersionUID = 4858945733404165431L; private String group; private String path; private String fileAbsolutePath; public FastDfsInfo(String group, String path) { this.group = group; this.path = path; } @Override public String toString() { return "FastDfsInfo{" + "group='" + group + '\'' + ", path='" + path + '\'' + '}'; } public String getGroup() { return group; } public void setGroup(String group) { this.group = group; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getFileAbsolutePath() { return fileAbsolutePath; } public void setFileAbsolutePath(String fileAbsolutePath) { this.fileAbsolutePath = fileAbsolutePath; }}
FastDFS 初始化工厂
/** * * @Description: FastDFS 初始化 * @author: Aaron * @date: 2017年7月12日 下午7:04:21 */public class FastDFSTemplateFactory { //连接超时时间 private int g_connect_timeout; //网络超时时间 private int g_network_timeout; //编码 private String g_charset; //tracker 端口 private int g_tracker_http_port; //防盗链token是否需要 private boolean g_anti_steal_token; //FastDFS key private String g_secret_key; //tracker 地址 private List<String> tracker_servers; //nginx 地址 private List<String> nginx_address; private TrackerGroup g_tracker_group; private PoolConfig poolConfig = new PoolConfig(); private String protocol = "http://"; private String sepapator = "/"; public void init() throws Exception { if (g_connect_timeout <= 0) { g_connect_timeout = ClientGlobal.DEFAULT_CONNECT_TIMEOUT; } if (g_network_timeout <= 0) { g_network_timeout = ClientGlobal.DEFAULT_NETWORK_TIMEOUT; } g_connect_timeout *= 1000; //millisecond g_network_timeout *= 1000; //millisecond if (g_charset == null || g_charset.length() == 0) { g_charset = "UTF-8"; } if (g_tracker_http_port <= 0) { g_tracker_http_port = 80; } if (tracker_servers == null || tracker_servers.isEmpty()) { throw new FastDFSException("item \"tracker_server\" not found", -1); } InetSocketAddress[] tracker_servers_socket = new InetSocketAddress[tracker_servers.size()]; for (int i = 0; i < tracker_servers.size(); i++) { String str = tracker_servers.get(i); String[] parts = str.split("\\:", 2); if (parts.length != 2) { throw new FastDFSException( "the value of item \"tracker_server\" is invalid, the correct format is host:port", -2); } tracker_servers_socket[i] = new InetSocketAddress(parts[0].trim(), Integer.parseInt(parts[1].trim())); } g_tracker_group = new TrackerGroup(tracker_servers_socket); if (g_anti_steal_token) { if (g_secret_key == null || "".equals(g_secret_key)) { throw new FastDFSException("item \"secret_key\" not found", -2); } } setToGlobal(); } private void setToGlobal() { ClientGlobal.setG_connect_timeout(this.g_connect_timeout); ClientGlobal.setG_network_timeout(this.g_network_timeout); ClientGlobal.setG_charset(this.g_charset); ClientGlobal.setG_tracker_http_port(this.g_tracker_http_port); ClientGlobal.setG_anti_steal_token(this.g_anti_steal_token); ClientGlobal.setG_secret_key(this.g_secret_key); ClientGlobal.setG_tracker_group(this.g_tracker_group); } public PoolConfig getPoolConfig() { if (poolConfig == null) { return new PoolConfig(); } return poolConfig; } public void setPoolConfig(PoolConfig poolConfig) { this.poolConfig = poolConfig; } public int getG_connect_timeout() { return g_connect_timeout; } public void setG_connect_timeout(int g_connect_timeout) { this.g_connect_timeout = g_connect_timeout; } public int getG_network_timeout() { return g_network_timeout; } public void setG_network_timeout(int g_network_timeout) { this.g_network_timeout = g_network_timeout; } public String getG_charset() { return g_charset; } public void setG_charset(String g_charset) { this.g_charset = g_charset; } public int getG_tracker_http_port() { return g_tracker_http_port; } public void setG_tracker_http_port(int g_tracker_http_port) { this.g_tracker_http_port = g_tracker_http_port; } public boolean isG_anti_steal_token() { return g_anti_steal_token; } public void setG_anti_steal_token(boolean g_anti_steal_token) { this.g_anti_steal_token = g_anti_steal_token; } public String getG_secret_key() { return g_secret_key; } public void setG_secret_key(String g_secret_key) { this.g_secret_key = g_secret_key; } public List<String> getTracker_servers() { return tracker_servers; } public void setTracker_servers(String tracker_servers) { this.tracker_servers = Arrays.asList(tracker_servers.split(",")); } public List<String> getNginx_address() { return nginx_address; } public void setNginx_address(String nginx_address) { this.nginx_address = Arrays.asList(nginx_address.split(",")); } public TrackerGroup getG_tracker_group() { return g_tracker_group; } public void setG_tracker_group(TrackerGroup g_tracker_group) { this.g_tracker_group = g_tracker_group; } public String getProtocol() { return protocol; } public void setProtocol(String protocol) { this.protocol = protocol; } public String getSepapator() { return sepapator; } public void setSepapator(String sepapator) { this.sepapator = sepapator; }}
FastDFS 模板类
/** * * @Description: FastDFS 模板类 * @author: Aaron * @date: 2017年7月12日 下午7:01:03 */public class FastDFSTemplate { private ConnectionPoolFactory connPoolFactory; private FastDFSTemplateFactory factory; public FastDFSTemplate(FastDFSTemplateFactory factory) { this.connPoolFactory = new ConnectionPoolFactory(factory); this.factory = factory; } /** * * @Description: 上传文件 * @param data * @param ext 后缀,如:jpg、bmp(注意不带.) * @return * @throws FastDFSException * @author: Aaron * @date: 2017年7月12日 下午7:01:32 */ public FastDfsInfo upload(byte[] data, String ext) throws FastDFSException { return this.upload(data, ext, null); } /** * * @Description: 上传文件 * @param data * @param ext 后缀,如:jpg、bmp(注意不带.) * @param values * @return * @throws FastDFSException * @author: Aaron * @date: 2017年7月12日 下午7:01:55 */ public FastDfsInfo upload(byte[] data, String ext, Map<String, String> values) throws FastDFSException { NameValuePair[] valuePairs = null; if (values != null && !values.isEmpty()) { valuePairs = new NameValuePair[values.size()]; int index = 0; for (Map.Entry<String, String> entry : values.entrySet()) { valuePairs[index] = new NameValuePair(entry.getKey(), entry.getValue()); index++; } } StorageClient client = getClient(); try { String[] uploadResults = client.upload_file(data, ext, valuePairs); String groupName = uploadResults[0]; String remoteFileName = uploadResults[1]; FastDfsInfo fastDfsInfo = new FastDfsInfo(groupName, remoteFileName); if (factory != null) { this.setFileAbsolutePath(fastDfsInfo); } return fastDfsInfo; } catch (Exception e) { throw new FastDFSException(e.getMessage(), e, 0); } finally { releaseClient(client); } } /** * * @Description: 下载文件 * @param dfs * @return * @throws FastDFSException * @author: Aaron * @date: 2017年7月12日 下午7:02:27 */ public byte[] loadFile(FastDfsInfo dfs) throws FastDFSException { return this.loadFile(dfs.getGroup(), dfs.getPath()); } /** * * @Description: 下载文件 * @param groupName * @param remoteFileName * @return * @throws FastDFSException * @author: Aaron * @date: 2017年7月12日 下午7:02:46 */ public byte[] loadFile(String groupName, String remoteFileName) throws FastDFSException { StorageClient client = getClient(); try { return client.download_file(groupName, remoteFileName); } catch (Exception e) { throw new FastDFSException(e.getMessage(), e, 0); } finally { releaseClient(client); } } /** * * @Description: 删除文件 * @param dfs * @throws FastDFSException * @author: Aaron * @date: 2017年7月12日 下午7:02:59 */ public void deleteFile(FastDfsInfo dfs) throws FastDFSException { this.deleteFile(dfs.getGroup(), dfs.getPath()); } /** * * @Description: 删除文件 * @param groupName * @param remoteFileName * @throws FastDFSException * @author: Aaron * @date: 2017年7月12日 下午7:03:13 */ public void deleteFile(String groupName, String remoteFileName) throws FastDFSException { int code; StorageClient client = getClient(); try { code = client.delete_file(groupName, remoteFileName); } catch (Exception e) { throw new FastDFSException(e.getMessage(), e, 0); } finally { releaseClient(client); } if (code != 0) { throw new FastDFSException(code); } } /** * * @Description: 设置远程可访问路径 * @param group * @param path * @return * @throws IOException * @throws NoSuchAlgorithmException * @throws MyException * @author: Aaron * @date: 2017年7月12日 下午7:03:34 */ public String setFileAbsolutePath(String group, String path) throws IOException, NoSuchAlgorithmException, MyException { int ts = (int) (System.currentTimeMillis() / 1000), port; String token = ""; if (factory.isG_anti_steal_token()) { token = ProtoCommon.getToken(path, ts, factory.getG_secret_key()); token = "?token=" + token + "&ts=" + ts; } List<String> addressList; if (factory.getNginx_address() != null) { addressList = factory.getNginx_address(); } else { addressList = factory.getTracker_servers(); } Random random = new Random(); int i = random.nextInt(addressList.size()); String[] split = addressList.get(i).split(":", 2); if (split.length > 1) { port = Integer.parseInt(split[1].trim()); } else { port = factory.getG_tracker_http_port(); } String address = split[0].trim(); return factory.getProtocol() + address + ":" + port + factory.getSepapator() + group + factory.getSepapator() + path + token; } public void setFileAbsolutePath(FastDfsInfo fastDfsInfo) throws IOException, NoSuchAlgorithmException, MyException { fastDfsInfo.setFileAbsolutePath(this.setFileAbsolutePath(fastDfsInfo.getGroup(), fastDfsInfo.getPath())); } protected StorageClient getClient() { StorageClient client = null; while (client == null) { try { client = connPoolFactory.getClient(); } catch (Exception e) { e.printStackTrace(); } } return client; } protected void releaseClient(StorageClient client) { connPoolFactory.releaseConnection(client); }}
测试类
/** * * @Description: 测试连接 * @author: Aaron * @date: 2017年7月12日 下午7:08:59 */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "classpath:spring-fastdfs.xml")public class MainTest { @Resource private FastDFSTemplate dfsTemplate; @Test public void testUploadAndDel() throws FastDFSException { FastDfsInfo rv = dfsTemplate.upload("".getBytes(), "txt"); System.out.println(rv); dfsTemplate.deleteFile(rv); } @Test public void testPool() throws InterruptedException { Runnable runnable = () -> { try { File file = new File("/Users/duhuifan/Downloads/edu-demo-fdfs/TestFile/aaron.jpg"); FileInputStream fis = new FileInputStream(file); byte[] b = new byte[fis.available()]; fis.read(b); Map<String, String> map = new HashMap<>(); FastDfsInfo rv = dfsTemplate.upload(b, "jpg", map); System.out.println(rv.getFileAbsolutePath()); //dfsTemplate.deleteFile(rv); } catch (Exception e) { e.printStackTrace(); } }; for (int i = 0; i < 1; i++) { new Thread(runnable).start(); } Thread.currentThread().join(); }}
GitHub项目源码
https://github.com/Aaron258/fastdfs-common.git
- FastDFS安装并 spring 集成(包含 Nginx)
- FastDFS+Nginx 集成并实现断点续传(一)
- FastDFS+Nginx 集成并实现断点续传(二)
- 【fastDFS】Nginx+FastDFS module安装
- centos安装FastDFS+Nginx
- fastdfs+nginx安装详解
- fastdfs+nginx安装配置
- FastDFS+Nginx安装配置
- fastdfs-nginx-module安装
- fastdfs+nginx安装详解
- CentOS安装FastDFS+Nginx
- fastdfs + nginx 安装部署
- centos安装FastDFS+Nginx
- nginx fastDFS 搭建安装
- centOS 6.5 Nginx集成fastDFS模块
- FastDFS NGINX集成与图片防盗
- FastDFS+Nginx安装配置笔记
- FastDFS+Nginx安装配置笔记
- char varchar varchar2 的区别
- 7/12 关于红包权限问题°
- PAT (Advanced Level) Practise 1072 Gas Station (30)
- Angular4项目部署到服务器上刷新404解决办法
- 实现自动出现滚动条
- FastDFS安装并 spring 集成(包含 Nginx)
- TensorFlow学习笔记【一】Helloworld,简单计算,线性回归
- json字符串转成 Map/List
- SASS学习
- 清除浮动、弹性盒模型
- radio单选按钮选中时当前页面实现跳转
- 迷宫-BFS
- js正则标志/g /i /m的用法,以及实例
- webservice