详解 FastDFS Docker安装 与 普通安装{附 Java 代码}

FastDFS

50张图片详解 VMware Workstation 16 + CentOS 7 下载与安装

【FastDFS 普通安装所需要的包】libfastcommonfastdfsfastdfs-nginx-module
百度云盘下载

【HHS 工具】Xshell&Xftp、FinalShell、SecureCRT&SecureFX

百度云盘下载

简介

FastDFS 由淘宝的余庆在 2008 年开源的一款轻量级分布式文件管理系统,FastDFS 用 C 语言实现,支持 Linux、MacOS 等 UNIX 系统。FastDFS 类似 Google FS,属于应用级文件系统,不是通用的文件系统,只能通过专有 API 访问,目前提供了 C 和 Java SDK ,以及 PHP 扩展 SDK。

FastDFS 专为互联网应用量身定做,解决大容量文件存储问题,追求高性能和高扩展性,它可以看做是基于文件的 key/value 存储系统,key 为文件 ID,value 为文件内容,因此称作分布式文件存储服务更为合适。

优势

大容量存储和高性能访问

架构

作为一款分布式文件管理系统,FastDFS 主要包括四个方面的功能:

  • 文件存储
  • 文件同步
  • 文件上传
  • 文件下载

FastDFS 官网的系统架构图:

FastDFS 官网的系统架构图

FastDFS 架构包括 Tracker 和 Storage 两部分,Tracker 用来追踪文件,相当于是文件的索引,而 Storage 则用来保存文件。

上传的文件最终保存在 Storage 上,文件的元数据信息保存在 Tracker 上,通过 Tracker 可以实现对 Storage 的负载均衡。

Storage 一般会搭建成集群,一个 Storage Cluster 可以由多个组构成,不同的组之间不进行通信,一个组又相当于一个小的集群,组由多个 Storage Server 组成,组内的 Storage Server 会通过连接进行文件同步来保证高可用。

安装

Docker 安装

安装
# 1、拉取镜像
docker pull delron/fastdfs
# 2、使用 docker 镜像构建 tracker 容器(跟踪服务器,起到调度的作用)
docker run -dti --network=host --name tracker -v /var/fdfs/tracker:/var/fdfs -v /etc/localtime:/etc/localtime delron/fastdfs tracker
# 3、使用 docker 镜像构建 storage 容器(存储服务器,提供容量和备份服务)
docker run -dti --network=host --name storage -e TRACKER_SERVER=192.168.226.128:22122 -e GROUP_NAME=group1 -v /var/fdfs/storage:/var/fdfs -v /etc/localtime:/etc/localtime delron/fastdfs storage

# 若不修改端口,跳过【4-6】
# 4、进入 storage 容器,到 storage 的配置文件中配置 http 访问的端口(默认:8888),配置文件在 /etc/fdfs 目录下的 storage.conf
	# 进入容器
	docker exec -it storage /bin/bash
	# 进入目录
	cd /etc/fdfs
	# 编辑文件
	vi storage.conf
# 5、修改 storage 中的 nginx (不需要安装)
	cd /usr/local/nginx/conf
	vi nginx.conf
# 6、修改完配置重启容器,没有修改就不需要重启
docker restart storage

# 开放端口
# nginx
firewall-cmd --zone=public --permanent --add-port=8888/tcp
# tracker
firewall-cmd --zone=public --permanent --add-port=22122/tcp
# storage
firewall-cmd --zone=public --permanent --add-port=23000/tcp
# 重启防火墙
systemctl restart firewalld
# 容器开机自启
docker update --restart=always tracker
docker update --restart=always storage
java客户端调用

结构

结构

依赖

<!-- Swagger3 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>
<!-- FastDFS -->
<dependency>
    <groupId>com.github.tobato</groupId>
    <artifactId>fastdfs-client</artifactId>
    <version>1.27.2</version>
</dependency>

配置

application.properties

# FastDFS 配置
# 读取时间
fdfs.so-timeout=1500
# 连接超时时间
fdfs.connect-timeout=600
# 缩略图
fdfs.thumb-image.width=150
fdfs.thumb-image.height=150
# Tracker 服务配置地址列表,确保 tracker storage nginx 已经启动
fdfs.tracker-list[0]=192.168.226.128:22122
fdfs.web-server-url=http://192.168.226.128:8888/

FdfsConfig

@Configuration
@Import(FdfsClientConfig.class) // 提供拥有 FastDFS 的 Java 客户端
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING) // 解决 JMX 重复注册 Bean 的问题
public class FdfsConfig {

}

Swagger2Config

@Configuration
public class Swagger2Config {

    @Bean
    Docket docket() {
        return new Docket(DocumentationType.OAS_30)
                // 配置网站的基本信息
                .apiInfo(new ApiInfoBuilder()
                        // 网站标题
                        .title("FastDFS接口文档")
                        // 标题后面的版本号
                        .version("v1.0")
                        .description("FastDFS接口文档")
                        // 联系人信息
                        .contact(new Contact("yueyazhui", "https://www.yueyazhui.top", "15235032479@163.com"))
                        .build())
                .select()
                // 指定接口的位置
                .apis(RequestHandlerSelectors.basePackage("top.yueyazhui.learnfastdfs02.controller"))
                .build();
    }
}

FdfsClientUtil

@Component
public class FdfsClientUtil {

    @Autowired
    private FastFileStorageClient fastFileStorageClient;
    @Value("${fdfs.web-server-url}")
    private String fdfsWebServerUrl;

    /**
     * 文件上传
     *
     * @param file
     * @return 返回文件路径(卷名和文件名)
     * @throws IOException
     */
    public String upload(MultipartFile file) throws IOException {
        if (file.isEmpty()) {
            return "文件不存在";
        }
        byte[] bytes = file.getBytes();
        long fileSize = file.getSize();
        String originalFilename = file.getOriginalFilename();
        String extension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        InputStream is = new ByteArrayInputStream(bytes);
        Set<MetaData> metaDataSet = new HashSet<MetaData>();
        metaDataSet.add(new MetaData("date", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")));
        metaDataSet.add(new MetaData("author", "yueyazhui"));
        StorePath storePath = fastFileStorageClient.uploadFile(is, fileSize, extension, metaDataSet);
        return fdfsWebServerUrl + storePath.getFullPath();
    }

    /**
     * 下载文件
     *
     * @param filePath 文件路径
     * @return 文件字节
     * @throws IOException
     */
    public byte[] download(String filePath) {
        byte[] bytes = null;
        if (StringUtils.isNotBlank(filePath)) {
            String group = filePath.substring(0, filePath.indexOf("/"));
            String path = filePath.substring(filePath.indexOf("/") + 1);
            DownloadByteArray byteArray = new DownloadByteArray();
            bytes = fastFileStorageClient.downloadFile(group, path, byteArray);
        }
        return bytes;
    }

    /**
     * 删除文件
     *
     * @param filePath 文件路径
     */
    public void delete(String filePath) {
        if (StringUtils.isNotBlank(filePath)) {
            fastFileStorageClient.deleteFile(filePath);
        }
    }
}

FileController

@Controller
@Api(tags = "文件")
public class FileController {

    @Autowired
    private FdfsClientUtil fdfsClientUtil;

    @GetMapping
    @ApiIgnore
    public String index() {
        return "index";
    }

    /**
     * 上传文件
     *
     * @param file 文件
     * @return 文件路径
     */
    @PostMapping(value = "upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @ResponseBody
    public String upload(@RequestPart("file") MultipartFile file) throws IOException {
        String filePath = fdfsClientUtil.upload(file);
        return filePath;
    }

    /**
     * 下载文件
     *
     * @param filePath 文件路径
     * @return
     */
    @GetMapping(value = "download")
    @ResponseBody
    @ApiOperation("下载")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "filePath", value = "文件路径", required = true),
            @ApiImplicitParam(name = "fileName", value = "文件名", required = true)
    })
    public ResponseEntity<byte[]> download(@RequestParam("filePath") String filePath, @RequestParam("fileName") String fileName) throws UnsupportedEncodingException {
        byte[] bytes = fdfsClientUtil.download(filePath);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentDispositionFormData("attachment", new String(fileName.getBytes("UTF-8"), "ISO-8859-1"));
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new ResponseEntity<>(bytes, headers, HttpStatus.CREATED);
    }

    /**
     * 删除文件
     *
     * @param filePath 文件路径
     * @return 删除结果
     */
    @DeleteMapping(value = "delete")
    @ResponseBody
    @ApiOperation("删除")
    @ApiImplicitParam(name = "filePath", value = "文件路径", required = true)
    public void delete(@RequestParam("filePath") String filePath) {
        fdfsClientUtil.delete(filePath);
    }
}

Swagger

普通安装

图片上传一般使用 FastDFS,图片上传成功后,图片访问一般采用 Nginx,因此 FastDFS 安装将从三个方面来介绍:

  • Tracker 安装
  • Storage 安装
  • Nginx 安装
Tracker 安装

首先需要准备一个环境两个库以及一个安装包。

一个环境

FastDFS 采用 C 语言开发,需要 gcc 环境,安装命令如下:

yum -y install gcc-c++

两个库

FastDFS 依赖 libevent 库,安装命令如下:

yum -y install libevent

FastDFS 运行所需要的基础库 libfastcommon,由 FastDFS 官方提供。

libfastcommon 下载地址

注:也可从文章开头的百度云盘中下载。

将下载好的 libfastcommon 拷贝至 /usr/local/ 目录下,然后依次执行如下命令:

cd /usr/local
tar -zxvf libfastcommon-1.0.43.tar.gz 
cd libfastcommon-1.0.43
./make.sh
./make.sh install

一个安装包

Tracker 和 Storage 安装包是相同的,下载一次即可。

安装文件可以从 FastDFS 的 GitHub 仓库上下载,下载地址

注:也可从文章开头的百度云盘中下载。

将下载好的文件拷贝到 /usr/local 目录下,然后依次执行如下命令安装:

cd /usr/local
tar -zxvf fastdfs-6.06.tar.gz
cd fastdfs-6.06
./make.sh
./make.sh install

安装成功后,执行如下命令,将安装目录的 conf 目录下的配置文件拷贝到 /etc/fdfs 目录下:

cd conf
cp ./* /etc/fdfs/

配置

进入 /etc/fdfs 目录下进行配置:

打开 tracker.conf 文件:

cd /etc/fdfs
vi tracker.conf

修改如下配置:

配置

默认端口是 22122,可以根据实际需求修改。然后配置一下元数据的保存目录(注意目录必须存在)。

启动

启动 Tracker:

/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf start

Tracker 安装成功。

Storage 安装

简单起见,搭建一个 Storage 实例即可。

Storage 安装也需要 libevent 和 libfastcommon,这两个库的安装参考上文。

Storage 安装,也和 Tracker 一致,执行命令也都一样,如果将 Tracker 和 Storage 安装在同一台服务器上。(相当于安装 Tracker 时已经安装了 Storage)

唯一需要做的,就是进入到 /etc/fdfs 目录下,配置 Storage:

cd /etc/fdfs
vi storage.conf

在这里插入图片描述
在这里插入图片描述

配置三个地方,分别是 base_path、store_path0 以及 tracker_server;tracker_server 模板有两个地址,如果只有一个 Tracker,配置一个,注释掉另一个。

配置完成后,执行如下命令启动 Storage:

/usr/bin/fdfs_storaged /etc/fdfs/storage.conf start

Tracker 和 Storage 启动完成后,就文件上传了;但上传的文件如果是图片,我们还需要提供一个图片的访问功能,目前的最佳方案 Nginx。

Nginx 安装

Nginx 是 FastDFS 的重要搭档。

Nginx 的安装分为两个步骤:

  • 安装 Nginx
  • 在 Storage 下安装 fastdfs-nginx-module

安装 Nginx

cd /root/install-package
wget http://nginx.org/download/nginx-1.22.0.tar.gz
tar -zxvf nginx-1.22.0.tar.gz
cd nginx-1.22.0
yum -y install pcre-devel
yum -y install openssl openssl-devel
./configure
make
make install
# 启动
cd /usr/local/nginx/sbin
./nginx
# 修改 Nginx 配置文件,重新加载 Nginx
./nginx -s reload

在这里插入图片描述

Nginx 启动成功之后,在浏览器中访问 Nginx 地址,看到此页面,表示 Nginx 已经安装成功了。

在 Storage 下安装 fastdfs-nginx-module

fastdfs-nginx-module 下载地址

注:也可从文章开头的百度云盘中下载。

将下载的文件拷贝到 /usr/local 目录下。然后进入 /usr/local 目录,分别执行如下命令:

cd /usr/local
tar -zxvf fastdfs-nginx-module-1.22.tar.gz

然后将 /usr/local/fastdfs-nginx-module-1.22/src/mod_fastdfs.conf 文件拷贝到 /etc/fdfs/ 目录下,并修改该文件的内容:

cp /usr/local/fastdfs-nginx-module-1.22/src/mod_fastdfs.conf /etc/fdfs/
vi /etc/fdfs/mod_fastdfs.conf

在这里插入图片描述

接下来,回到第一步下载的 nginx 安装文件的解压目录中,执行如下命令,重新配置编译安装:

cd /root/install-package/nginx-1.22.0
./configure --add-module=/usr/local/fastdfs-nginx-module-1.22/src
make
make install

安装完成后,修改 nginx 的配置文件,如下:

vi /usr/local/nginx/conf/nginx.conf

在这里插入图片描述

在这里配置 nginx 请求转发。

配置完成后,启动 nginx;

cd /usr/local/nginx/sbin
ps aux | grep nginx
kill -9 25665
kill -9 25666
./nginx

在这里插入图片描述

看到如下日志,表示 nginx 启动成功:

ngx_http_fastdfs_set pid=25899

fastdfs-nginx-module 的作用

Storage 由很多组构成,每个组又是一个小的集群,在每一个组里边,数据会进行同步,但是如果数据还没同步,这个时候就有请求发来了,该怎么办?此时fastdfs-nginx-module 会直接从源 Storage 上获取文件。

安装成功了。

Java 客户端调用

依赖:

<dependency>
    <groupId>net.oschina.zcx7878</groupId>
    <artifactId>fastdfs-client-java</artifactId>
    <version>1.27.0.0</version>
</dependency>

在项目的 resources 目录下添加 FastDFS 的配置文件 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 = yueyazhui
fastdfs.http_tracker_http_port = 80

fastdfs.tracker_servers = 47.95.1.150:22122

## Whether to open the connection pool, if not, create a new connection every time
fastdfs.connection_pool.enabled = true

## max_count_per_entry: max connection count per host:port , 0 is not limit
fastdfs.connection_pool.max_count_per_entry = 500

## connections whose the idle time exceeds this time will be closed, unit: second, default value is 3600
fastdfs.connection_pool.max_idle_time = 3600

## Maximum waiting time when the maximum number of connections is reached, unit: millisecond, default value is 1000
fastdfs.connection_pool.max_wait_time_in_ms = 1000

fastdfs.tracker_servers Tracker 的地址,根据实际情况配置即可。

fastdfs.http_secret_key 秘钥。

代码如下:

StorageClient1 client1 = null;

@BeforeEach
void before() throws MyException, IOException {
    // 加载配置文件
    ClientGlobal.initByProperties("fastdfs-client.properties");
    // 构建TrackerClient
    TrackerClient trackerClient = new TrackerClient();
    // 获得TrackerServer
    TrackerServer trackerServer = trackerClient.getConnection();
    // 初始化StorageServer
    StorageServer storageServer = null;
    // 获得一个StorageClient1
    client1 = new StorageClient1(trackerServer, storageServer);
}

@Test
void upload() throws MyException, IOException {
    // 元数据信息(额外信息)
    NameValuePair pairs[] = null;
    // 上传
    String fileId = client1.upload_file1("C:\\Users\\15235\\Pictures\\Saved Pictures\\images\\avatar_admin.gif", "gif", pairs);
    System.out.println("fileId = " + fileId);
}

@Test
void download() throws MyException, IOException {
    // 下载
    byte[] bytes = client1.download_file1("group1/M00/00/00/L18BlmNQ7Q-ALxnTAAItxHZKwEI729.gif");
    FileOutputStream fos = new FileOutputStream(new File("C:\\Users\\15235\\Pictures\\Saved Pictures\\images\\avatar_admin-copy.gif"));
    fos.write(bytes);
    fos.close();
}
安全访问

访问时,加一个上传时候的令牌即可。

首先在服务端开启令牌校验:

vi /etc/fdfs/http.conf

在这里插入图片描述

配置完成后,记得重启服务端:

cd /usr/local/nginx/sbin
./nginx -s stop
./nginx

获取令牌,代码如下:

@Test
void token() throws MyException, UnsupportedEncodingException, NoSuchAlgorithmException {
    // 获取时间戳
    int ts = (int) Instant.now().getEpochSecond();
    // 获取Token
    String token = ProtoCommon.getToken("M00/00/00/L18BlmNQ7Q-ALxnTAAItxHZKwEI729.gif", ts, "yueyazhui");
    StringBuffer sb = new StringBuffer();
    sb
        .append("http://47.95.1.150/")
        .append("group1/M00/00/00/L18BlmNQ7Q-ALxnTAAItxHZKwEI729.gif")
        .append("?token=")
        .append(token)
        .append("&ts=")
        .append(ts);
    System.out.println("sb.toString() = " + sb.toString());
}

主要是根据 ProtoCommon.getToken 方法来获取令牌,注意这个方法的第一个参数是你要访问的文件 id,**注意,这个地址里边不包含 group;**第二个参数是时间戳,第三个参数是密钥,密钥要和服务端的配置一致。

将生成的字符串拼接,追加到访问路径后面,如:http://47.95.1.150/group1/M00/00/00/L18BlmNQ7Q-ALxnTAAItxHZKwEI729.gif?token=108711d7651b1b78905896181d7693cb&ts=1666256470。「此时访问路径里边如果没有令牌,会访问失败。」

完成!

摘录:江南一点雨 FastDFS

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月牙坠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值