场景概述
如何存储大量的图片和视频?
在用户访问量大的情况下,如何保证下载速度?
这些问题都需要分布式文件系统来解决。
什么是文件系统
文件数据是如何存储的?
应用软件 -> 操作系统,文件系统 -> 驱动程序 -> 机械硬盘 HDD,固态硬盘 SSD,光盘 CD ROM
文件数据存储在硬盘中。
分布式文件系统
一台电脑存储量有限,并且并发吞吐量也有限,如何提高性能?
分布式:不同的业务模块部署在不同的服务器上或者同一个业务模块拆分为多个子业务,部署在不同的服务器上,解决高并发的问题。
集群:同一个业务部署在多台服务器上,提高系统的高可用。
主流的分布式文件系统
HDFS
Hadoop Distributed File System - Hadoop 分布式文件系统;
高容错的系统,适合部署到廉价的机器上;
能提供高吞吐量的数据访问,非常适合大规模数据应用;
HDFS 采用主从结构,一个 HDFS 是由一个 name 节点和 N 个 data 节点组成;
Name 节点储存元数据,一个文件分割成 N 份存储在不同的 data 节点上。
GFS
Google File System 可扩展的分布式文件系统;
用于大型的,分布式的,对大量数据进行访问的应用;
运行于廉价的普通硬件上,可以提供容错功能;
它可以给大量的用户提供总体性能较高的服务;
GFS 采用主从结构,一个 GFS 集群由一个 master 和大量的 chunkserver(分块服务器)组成;
一个文件被分割若干块,分散储存到多个分块 server 中。
FastDFS
专为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用 FastDFS 很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务;
HDFS,GFS 等都是通用的文件系统,他们的优点是开发体验好,但是系统的复杂度较高,性能也一般;
相比之下,专用的分布式文件系统体验差,但是复杂度低,性能也高,而 FastDFS 特别适合图片,小视频等小文件,因为 FastDFS 对文件是不分割的,所以没有文件合并的开销;
网络通信用 socket,速度快。
工作原理
FastDFS 包含 Tracker Server 和 Storage Server;
Client 客户端请求 Tracker Server 进行文件的上传与下载;
Tracker Server 调度 Storage Server 最终完成 Client 和 Storage Server 之间的上传和下载。
Tracker Server:
- 作用是负载均衡和调度,它管理着存储服务(Storage Server),可以理解为:“大管家,追踪者,调度员”;
- Tracker Server 可以通过集群实现高可用,策略为“轮询”。
Storage Server:
- 作用是文件存储,客户端上传的文件最终存储到 Storage 服务器上;
- Storage 集群采用分组的方式,同组内的每台服务器是平等关系,数据同步,目的是实现数据备份,从而高可用,而不同组的服务器之间是不通信的;
- 同组内的每台服务器的存储量不一致的情况下,会选取容量最小的那个,所以同组内的服务器之间软硬件最好保持一致。
- Storage Server 会连接集群中的所有 Tracker Server,定时向他们汇报自己的状态,例如:剩余空间,文件同步情况,文件上传下载次数等信息。
上传 / 下载原理
上传:
1)Storage 定时向 Tracker 上传状态信息。
2)Client 向 Tracker 发送上传连接请求。
3)Tracker 查询可用的 Storage。
4)Tracker 返回信息(Storage 的 ip 和端口)给 Client。
5)Client 上传文件(file content 和 metadata)到 Storage,Storage 生成 file_id。
6)Storage 将上传文件内容写入磁盘,然后返回 file_id(路径信息和文件名)给 Client。
7)Client 存储文件信息。
下载:
1)Storage 定时向 Tracker 上传状态信息。
2)Client 向 Tracker 发送下载连接请求。
3)Tracker 查询可用的 Storage。
4)Tracker 返回信息(Storage 的 ip 和端口)给 Client。
5)Client 发送要下载的 file_id(组名,路径,文件名)到 Storage,Storage 查找对应的文件。
6)Storage 返回 file_content 给 Client。
客户端上传文件后,storage 会将文件 id 返回给客户端,格式如下:
group1/M00/02/11/wKi6gF98h5CAFzjXAAG0AJOCxpA105.jpg
group1 组名:文件上传后,在 storage 组的名称,文件上传成功后,由 storage 返回,需要客户端自行保存。
M00 虚拟磁盘路径:
- storage 配置的虚拟路径,在磁盘选项 storage_path 对应;
- storage_path0 对应 M00;
- storage_path1 对应 M01。
02/11 数据两级目录:storage 在虚拟磁盘下自行创建的目录。
wKi6gF98h5CAFzjXAAG0AJOCxpA105.jpg 文件名:与上传时不同,是用 storage 根据特定信息生成的,里面包含 storage 服务器的 ip,创建时间戳,大小,后缀名等信息。
FastDFS 的上传与下载
安装
安装 gcc(编译时需要)
yum install -y gcc gcc-c++
安装 libevent(运行时需求)
yum -y install libevent
安装 libfastcommon
libfastcommon 是 FastDFS 官方提供的,libfastcommon 包含了 FastDFS 运行所需要的一些基础库。
1)上传 libfastcommon-master.zip 到 /opt
# 安装解压 zip 包的命令
yum install -y unzip
# 解压包
unzip libfastcommon.zip
# 进入目录
cd libfastcommon-master
2)编译
./make.sh
如果:make.sh 的执行权限没有开启,则需要开启执行权限:
chmod 777 make.sh
3)安装
./make.sh install
libfastcommon 安装好后会在 /usr/lib64 目录下生成 libfastcommon.so 库文件。
4)拷贝库文件
[root@localhost lib64]# cd /usr/lib64
[root@localhost lib64]# ll | grep libfastcommon
-rwxr-xr-x. 1 root root 1016391 Oct 6 07:10 libfastcommon.so
# 显示已经有了,就不需要拷贝了
[root@localhost lib64]# cp libfastcommon.so /usr/lib
cp: ‘libfastcommon.so’ and ‘/usr/lib/libfastcommon.so’ are the same file
安装 Tracker
下载 FastDFS_v5.05.tar.gz,并上传到 /opt:
tar -zxvf FastDFS_v5.05.tar.gz
cd FastDFS
./make.sh
./make.sh install
安装成功将安装目录下的 conf 下的文件拷贝到 /etc/fdfs/ 目录下:
cp /opt/FastDFS/conf/* /etc/fdfs/
配置
Tracker 配置
vim /etc/fdfs/tracker.conf
由配置文件可以知道,Tracker Server 的端口号 port 为 22122。
修改基础目录(Tracker 运行时会向此目录存储 storage 的管理数据):
# the base path to store data and log files
base_path=/home/fastdfs
基础目录不存在的话,需要自行创建:mkdir /home/fastdfs
Storage 配置
vim /etc/fdfs/storage.conf
由配置文件可以知道,Storage Server 的端口号为 23000,组名 group_name = group1,每秒心跳间隔 heart_beat_interval = 30。
修改配置文件如下:
# the base path to store data and log files
base_path=/home/fastdfs
...
# store_path#, based 0, if store_path0 not exists, it's value is base_path
# the paths must be exist
store_path0=/home/fastdfs/fdfs_storage
#store_path1=/home/fastdfs2
...
# tracker_server can ocur more than once, and tracker_server format is
# "host:port", host can be hostname or ip address
tracker_server=192.168.186.128:22122
如果 fdfs_storage 目录不存在,需要自行创建:mkdir /home/fastdfs/fdfs_storage。
启动服务
启动 tracker:
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart
启动 storage:
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart
查看所有运行的端口:
netstat -ntlp | grep fdfs
开放对应的防火墙端口:
firewall-cmd --zone=public --add-port=23000/tcp --permanent
firewall-cmd --zone=public --add-port=22122/tcp --permanent
firewall-cmd --reload
搭建 Java 工程
使用 IDEA 创建 maven 工程
pom.xml
<!-- 指定编码及版本 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>1.11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!-- fastdfs 的 java 客户端-->
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
创建配置文件
在 resources 下创建 config 目录,在 config 目录下创建 fastdfs-client.properties,内容如下:
## fastdfs-client.properties
fastdfs.connect_timeout_in_seconds = 5
fastdfs.network_timeout_in_seconds = 30
fastdfs.charset = UTF-8
fastdfs.http_anti_steal_token = false
fastdfs.http_secret_key = FastDFS1234567890
fastdfs.http_tracker_http_port = 80
fastdfs.tracker_servers = 192.168.186.128:22122
文件上传
com.renda.test.TestUpload
public class TestUpload {
public static void main(String[] args) throws IOException, MyException {
// 加载配置文件
ClientGlobal.initByProperties("config/fastdfs-client.properties");
// 创建 tracker 客户端
TrackerClient trackerClient = new TrackerClient();
// 通过 tracker 客户端获取 tracker 的连接服务并返回
TrackerServer trackerServer = trackerClient.getConnection();
// 声明 storage 服务
StorageServer storageServer = null;
// 定义 storage 客户端
StorageClient1 client = new StorageClient1(trackerServer, storageServer);
?
// 定义文件元信息
NameValuePair[] list = new NameValuePair[1];
list[0] = new NameValuePair("fileName", "1.jpg");
String fileID = client.upload_file1("E:\\upload\\1.jpg", "jpg", list);
?
// group1/M00/00/00/wKi6gF98h5CAFzjXAAG0AJOCxpA105.jpg
/*
group1:一台服务器,就是一个组
M00: store_path0 ----> /home/fastdfs/fdfs_storage/data
00/00:两级数据目录
*/
System.out.println("fileID = " + fileID);
?
// 关闭 tracker 服务
trackerServer.close();
}
?
}
执行下面命令可以在服务器中查看上传的文件:
ll /home/fastdfs/fdfs_storage/data/00/00/
文件查询
public class TestQuery {
?
public static void main(String[] args) throws IOException, MyException {
// 加载配置文件
ClientGlobal.initByProperties("config/fastdfs-client.properties");
// 创建 tracker 客户端
TrackerClient trackerClient = new TrackerClient();
// 通过 tracker 客户端获取 tracker 的连接服务并返回
TrackerServer trackerServer = trackerClient.getConnection();
// 声明 storage 服务
StorageServer storageServer = null;
// 定义 storage 客户端
StorageClient1 client = new StorageClient1(trackerServer, storageServer);
?
// 获取文件信息
// fileInfo = source_ip_addr = 192.168.186.128, file_size = 111616, create_timestamp = 2020-10-06 23:04:48, crc32 = -1820146032
FileInfo fileInfo = client.query_file_info1("group1/M00/00/00/wKi6gF98h5CAFzjXAAG0AJOCxpA105.jpg");
if (fileInfo != null) {
System.out.println("fileInfo = " + fileInfo);
} else {
System.out.println("查无此文件!");
}
?
// 关闭 tracker 服务
trackerServer.close();
}
?
}
文件下载
public class TestDownload {
public static void main(String[] args) throws IOException, MyException {
// 加载配置文件
ClientGlobal.initByProperties("config/fastdfs-client.properties");
// 创建 tracker 客户端
TrackerClient trackerClient = new TrackerClient();
// 通过 tracker 客户端获取 tracker 的连接服务并返回
TrackerServer trackerServer = trackerClient.getConnection();
// 声明storage服务
StorageServer storageServer = null;
// 定义 storage 客户端
StorageClient1 client = new StorageClient1(trackerServer, storageServer);
// 文件信息
byte[] bytes = client.download_file1("group1/M00/00/00/wKi6gF98h5CAFzjXAAG0AJOCxpA105.jpg");
// 通过 io 将字节数组,转换成一个文件
FileOutputStream fileOutputStream = new FileOutputStream(new File("E:/download/xxxxxx.jpg"));
fileOutputStream.write(bytes);
System.out.println("下载完毕");
// 关闭
fileOutputStream.close();
trackerServer.close();
}
}
项目实战
掌握 FastDFS 在真实项目中的使用方法。
掌握 FastDFS 实现图片服务器。
搭建图片服务器
Nginx 模块安装(Storage)
1)上传 fastdfs-nginx-module_v1.16.tar.gz 到 /opt
2)解压 nginx 模块
tar -zxvf fastdfs-nginx-module_v1.16.tar.gz
3)修改 config 文件,将文件中的 /usr/local/ 路径改为 /usr/
cd /opt/fastdfs-nginx-module/src
vim config
4)将 fastdfs-nginx-module/src下的 mod_fastdfs.conf 拷贝至 /etc/fdfs 下
cp mod_fastdfs.conf /etc/fdfs/
5)修改 /etc/fdfs/mod_fastdfs.conf
...
# the base path to store log files
base_path=/home/fastdfs
...
# FastDFS tracker_server can ocur more than once, and tracker_server format is
# "host:port", host can be hostname or ip address
# valid only when load_fdfs_parameters_from_tracker is true
tracker_server=192.168.186.128:22122
...
# if the url / uri including the group name
# set to false when uri like /M00/00/00/xxx
# set to true when uri like ${group_name}/M00/00/00/xxx, such as group1/M00/xxx
# default value is false
url_have_group_name = true
...
# store_path#, based 0, if store_path0 not exists, it's value is base_path
# the paths must be exist
# must same as storage.conf
store_path0=/home/fastdfs/fdfs_storage
#store_path1=/home/fastdfs1
...
6)将 libfdfsclient.so 拷贝至 /usr/lib 下
cp /usr/lib64/libfdfsclient.so /usr/lib/
7)如果没有就创建 nginx/client 目录
mkdir -p /var/temp/nginx/client
Nginx 安装(Tracker)
1) 将 nginx-1.14.0.tar.gz 上传到 /usr(安装过 nginx,此步省略)
2) 解压:tar -zxvf nginx-1.14.0.tar.gz(安装过 nginx,此步省略)
3) 安装依赖库(安装过 nginx,此步省略)
yum install pcre
yum install pcre-devel
yum install zlib
yum install zlib-devel
yum install openssl
yum install openssl-devel
4) 进入 nginx 解压的目录下 cd /usr/nginx-1.14.0
5) 安装(重新配置 Nginx,增加 Nginx 的 FastDFS 模块组件 /opt/fastdfs-nginx-module/src)
./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi \
--add-module=/opt/fastdfs-nginx-module/src
注意:上边将临时文件目录指定为 /var/temp/nginx,需要在 /var 下创建 temp 及 nginx 目录:mkdir /var/temp/nginx
6) 编译:make
7) 安装:make install
8) 拷贝配置文件
[root@localhost conf]# cd /opt/FastDFS/conf/
[root@localhost conf]# cp http.conf mime.types /etc/fdfs/
cp: overwrite ‘/etc/fdfs/http.conf’? yes
cp: overwrite ‘/etc/fdfs/mime.types’? yes
9) 修改 nginx 配置文件
cd /usr/local/nginx/conf/
vim nginx.conf# 配置 FastDFS 服务器测试
server {
listen 80;
server_name 192.168.186.128;
location /group1/M00 {
root /home/fastdfs/fdfs_storage/data;
ngx_fastdfs_module;
}
}
10) 关闭 nginx,重新启动 nginx
pkill -9 nginx
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
11) 本地访问 nginx 并查看图片
http://192.168.186.128
http://192.168.186.128/group1/M00/00/00/wKi6gF98h5CAFzjXAAG0AJOCxpA105.jpg
搭建 web 项目
pom.xml
<packaging>war</packaging>
<!-- 指定编码及版本 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>1.11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!-- 因为有 jsp 页面,所以引用 servlet 依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
<version>2.5</version>
</dependency>
<!-- 页面提交过来的请求,使用 springMVC 来处理-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<!-- java 连接 FastDFS 的客户端工具 -->
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0.0</version>
</dependency>
<!-- 图片上传到 FastDFS 需要用的到 IO 工具 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 图片保存到 web 服务器需要用到的 IO 工具 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!-- 用来转换 java 对象和 json 字符串,注意,2.7 以上版本必须搭配 spring 5.0 以上 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<port>8001</port>
<path>/</path>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
创建前端页面
src\main\webapp\index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>上传图片</title>
</head>
<body>
?
<%-- 上传文件,文件与文字相比较起来,属于内容较大,必须使用 post 方式提交 --%>
<%-- 上传文件,和普通文件有区别,action 接收参数也会区别对待,所以声明带文件提交的表单为“多部件表单” --%>
<form action="upload" method="post" enctype="multipart/form-data">
<input type="file" name="fname">
<br>
<button>提交</button>
</form>
?
</body>
</html>
src\main\webapp\WEB-INF\web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
?
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
?
</web-app>
资源配置
src\main\resources\spring\spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
?
<!-- 扫描注解的包 -->
<context:component-scan base-package="com.renda.controller"/>
?
<!-- 扫描控制器中的注解:@Response -->
<mvc:annotation-driven/>
?
<!-- 上传文件的解析器(规定上传文件的大小限制)-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传文件最大限制:2 GB -->
<property name="maxUploadSize" value="2048000000"/>
</bean>
?
</beans>
src\main\resources\config\fastdfs-client.properties
## fastdfs-client.properties
fastdfs.connect_timeout_in_seconds = 5
fastdfs.network_timeout_in_seconds = 30
fastdfs.charset = UTF-8
fastdfs.http_anti_steal_token = false
fastdfs.http_secret_key = FastDFS1234567890
fastdfs.http_tracker_http_port = 80
fastdfs.tracker_servers = 192.168.186.128:22122
文件实体类
com.renda.entity.FileSystem
public class FileSystem implements Serializable {
?
private static final long serialVersionUID = -4517479391868763329L;
private String fileId;
private String filePath;
private String fileName;
?
public FileSystem() {
}
?
public FileSystem(String fileId, String filePath, String fileName) {
this.fileId = fileId;
this.filePath = filePath;
this.fileName = fileName;
}
?
// Getter, Setter, toString ...
?
}
控制层
com.renda.controller.FileAction
@Controller
public class FileAction {
?
/**
* MultipartHttpServletRequest:
* 是 httpServletRequest 的强化版本,
* 不仅可以装文本信息,还可以装图片文件信息。
* <p>
* 上传文件的流程:
* 1、先把文件保存到 web 服务器上
* 2、再从web服务器上将文件 上传 到 FastDFS 上
*
* @param request 多部件表单的请求对象
* @return 上传文件对象的 json 对象
*/
@RequestMapping("upload")
@ResponseBody
public FileSystem upload(MultipartHttpServletRequest request) throws IOException, MyException {
FileSystem fileSystem = new FileSystem();
?
/* 1、把文件保存到 web 服务器 */
// 从页面请求中,获取上传的文件对象
MultipartFile file = request.getFile("fname");
// 从文件对象中获取 文件的原始名称
String originalFilename = file.getOriginalFilename();
// 通过字符串截取的方式,从文件原始名中获取文件的后缀 .jpg
String filenameSuffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
// 为了避免文件因为同名而覆盖,生成全新的文件名
String newFileName = UUID.randomUUID().toString() + "." + filenameSuffix;
// 创建 web 服务器本地保存文件的目录(预先创建好 E:/upload 目录,否则系统找不到路径,会抛异常)
File newFileSaveAtLocal = new File("E:/upload/" + newFileName);
// 将路径转换成文件
file.transferTo(newFileSaveAtLocal);
// 获取本地保存文件的目录的绝对路径
String newFilePathAtLocal = newFileSaveAtLocal.getAbsolutePath();
?
/* 2、把文件从 web 服务器上传到 FastDFS 服务器 */
// 加载配置文件
ClientGlobal.initByProperties("config/fastdfs-client.properties");
// 创建 tracker 客户端
TrackerClient trackerClient = new TrackerClient();
// 通过 tracker 客户端获取 tracker 的连接服务并返回
TrackerServer trackerServer = trackerClient.getConnection();
// 声明 storage 服务
StorageServer storageServer = null;
// 定义 storage 客户端
StorageClient1 client = new StorageClient1(trackerServer, storageServer);
// 定义文件元信息
NameValuePair[] list = new NameValuePair[1];
list[0] = new NameValuePair("fileName", originalFilename);
String fileID = client.upload_file1(newFilePathAtLocal, filenameSuffix, list);
// 关闭 tracker 服务
trackerServer.close();
// 封装 fileSystem 数据对象
fileSystem.setFileId(fileID);
fileSystem.setFileName(originalFilename);
// 已经上传到 FastDFS 上,通过 fileId 来访问图片,所以 fileId 即为文件路径
fileSystem.setFilePath(fileID);
?
return fileSystem;
}
?
}
启动 FastDFS 相关服务,测试开始
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
netstat -ntlp
上传图片,前端返回数据:
{"fileId":"group1/M00/00/00/wKi6gF98ogyAbbbTAAG0AJOCxpA877.jpg","filePath":"group1/M00/00/00/wKi6gF98ogyAbbbTAAG0AJOCxpA877.jpg","fileName":"Buddha-head.jpg"}
通过 Ngnix 访问 FastDFS 服务器:
http://192.168.186.128/group1/M00/00/00/wKi6gF98ogyAbbbTAAG0AJOCxpA877.jpg
或者直接执行命令查看图片:
cd /home/fastdfs/fdfs_storage/data/00/00/
ls
想了解更多,欢迎关注我的微信公众号:Renda_Zhang
本文暂时没有评论,来添加一个吧(●'◡'●)