Title

springboot集成FastDFS使用实现防盗链功能

关于FastDFS

FastDFS是一个高性能的分布式⽂件系统。
FastDFS是由Tracker server(追踪调度服务器) 和 Storage server(文件存储服务器)组成。
Storage server(文件存储服务器)又是由多个组构成

Tracker server(追踪调度服务器)
Tracker server(追踪调度服务器),作⽤是负载均衡和调度,通过 Tracker server 在⽂件上传时可以根据⼀些策略找到Storage server 提供⽂件上传服务,所以将 tracker server称为追踪服务器或调度服务器。

Storage server(文件存储服务器)
Storage server(文件存储服务器) 作⽤是⽂件存储,客户端上传的⽂件最终存储在 Storage 服务器上,Storage server 没有实现⾃⼰的⽂件系统⽽是利⽤操作系统的⽂件系统来管理⽂件,所以将storage称为存储服务器。

Group(组)

1.由于Storage server(文件存储服务器)是用来存储文件的,具有容量限制,为了解决该问题,提出扩容分组,所以延伸出组的概念。
2.每个组存放部分文件,且每个组之间保存的⽂件是不同的。
3.为保证每个组内的节点服务高可用,允许组内构建存储服务器集群,每个组内部可以有多个成员,组成员内部保存的内容是⼀样的,组成员的地位是⼀致的,没有主从的概念。
4.由于文件存放在每个组的节点上,所以为了方便http访问调用,每个Storage server还要绑定一个nginx。
5.所有的组加起来是一个完成的Storage server(文件存储服务器)。

docker安装FastDFS

  • 1.安装步骤

1.拉取fastdfs镜像

docker pull delron/fastdfs

2.创建Tracker server(追踪调度服务器)容器

提示:在指定虚拟机镜像之后,还需要添加tracker命令,这样镜像就会根据tracker命令启动tracker服务

docker run -d --name tracker --net=host -p 22122:22122 -v /var/fastdfs/tracker:/var/fdfs delron/fastdfs tracker

–net=host : 将虚拟机的网络应用于容器,也就是说和宿主机网络一致

3.Storage server(文件存储服务器),需要指定Tracker 的ip和端口

提示:在指定虚拟机镜像之后,还需要添加storager命令,这样镜像就会根据storage命令启动storage服务

docker run -d --name storage --net=host -p 8888:8888 -p 23000:23000 -e TRACKER_SERVER=192.168.130.160:22122 -e GROUP_NAME=group1 -v /var/fastdfs/storage:/var/fdfs delron/fastdfs storage

GROUP_NAME=group1 : 指定服务器在组group1中或者新增一个组叫group1,如果想要增加新的组用于扩容 ,再次运行该命令,更换新组名即可。
–net=host : 将虚拟机的网络应用于容器,也就是说和宿主机网络一致

  • 2.修改nginx配置

storage内部已经集成了nginx,这里的nginx可以使图片在浏览器中访问到

1.进入Storage容器内

提示:进入Storage容器内【cd /etc/fdfs/ 】也有Storage和Tracker的配置

docker exec -it storage /bin/bash

2.编辑文件【nginx.conf】文件

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

3.如果i进行了配置修改 则需要重启

docker restart storage

使用步骤

1.导包

<!--fastdfs文件存储-->
<dependency>
    <groupId>com.github.tobato</groupId>
    <artifactId>fastdfs-client</artifactId>
    <version>1.26.7</version>
    <exclusions>
        <exclusion>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </exclusion>
    </exclusions>
</dependency>

2.添加配置

在【application.yml】添加配置

fdfs:
  so-timeout: 1500 #读取超时时间
  connect-timeout: 600 #连接超时时间
  thumb-image: #缩略图参数
    width: 150
    height: 150
  tracker-list: 192.168.136.160:22122 #tracker服务器地址 可配置多个
  web-server-url: http://192.168.136.160:8888 #访问路径 storage中nginx地址

测试

import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.server.AppServerApplication;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.File;
import java.io.IOException;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = AppServerApplication.class)
public class FastDFSTest {
    @Autowired
    protected FastFileStorageClient storageClient;
    @Autowired
    private FdfsWebServer fdfsWebServer;

    @Test
    public void testUpload() {
        String path = "D:\\IMAGE\\2e8e06bd-bfe3-4af3-9540-83eb20982656.jpg";
        File file = new File(path);
        try {
            //上传图片
            StorePath storePath = this.storageClient.uploadFile(FileUtils.openInputStream(file), file.length(), "jpg", null);
            //拼接路径   可通过该路径访问上传的照片  http://192.168.136.160:8888/group1/M00/00/00/wKiIoGMB7PmAUPZZAAHMYGEwMhg147.jpg
            String url = fdfsWebServer.getWebServerUrl() + "/" + storePath.getFullPath();
            System.out.println(url);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

fastdfs开启防盗链功能

实现原理

1.fastdfs是一个分布式文件系统,如果我们的fastdfs部署在外网,那么任何一个人知道了我们的上传接口,那么它就可以文件的上传和访问。那么我们如何阻止他人访问我们fastdfs服务器上的文件呢?因此就需要使用fastdfs的防盗链功能。

2.原理:fastdfs的防盗链是通过token机制来实现的。当我们开启防盗链功能后,需要在url后增加2个额外的参数token和ts。token和ts的生成都是需要在服务端。

开启防盗链

FastDFS扩展模块内置了通过token来实现防盗链的功能。开启防盗链后,访问文件是需要在url中加两个参数:token和ts。ts为时间戳,token为系统根据时间戳和密码生成的信物。

进入 storage 容器 打开:

vi /etc/fdfs/http.conf

# true 表示开启防盗链
http.anti_steal.check_token = true
# token的过期时间,单位为秒
http.anti_steal.token_ttl = 300
# 密钥,不可泄漏,用于生成token
http.anti_steal.secret_key = thisisasecuritykey
# 当图片拒绝访问后,显示的图片,此图片需要可访问,不然可能会出现问题,放到容器里 使用 chmod -R 777 /data/fastdfs/404.jpg 授权
http.anti_steal.token_check_fail = /data/fastdfs/404.jpg

http.anti_steal.token_check_fail 指定的图片需要可访问,否则可能会出现问题,可以对应 storage 容器的 nginx 日志查看,包括调试网络

重启nginx

/usr/local/nginx/sbin/nginx -s reload

Java代码生成授权token

1.token生成规则

token = md5(文件ID+私钥+时间戳) 文件ID:不能包含group

group1/M00/00/00/wKh5iWNBl7-AKvj1AAAwWD4VeAg577.jpg
`需要替换成`
M00/00/00/wKh5iWNBl7-AKvj1AAAwWD4VeAg577.jpg

私钥:需要和 /etc/fdfs/http.conf 中的 http.anti_steal.secret_key 值一致
时间戳:单位秒

2.java生成token

   /**
     * 生成防盗链token
     * @param remoteFilename 文件路径,不带group:M00/00/00/wKg4C1tFmTWAFPKBAADdeFFxlXA240.png
     * @param httpHost         文件服务器web访问地址
     * @param secretKey         密码
     * @return
     * @throws UnsupportedEncodingException
     * @throws NoSuchAlgorithmException
     * @throws MyException
     */
    public static String getSourceUrl(String remoteFilename, String httpHost,String secretKey) throws UnsupportedEncodingException, NoSuchAlgorithmException, MyException {
        int lts = (int)(System.currentTimeMillis() / 1000);
        String token = ProtoCommon.getToken(remoteFilename, lts, secretKey); //初始化secret_key
        return httpHost + "/" + remoteFilename + "?token=" + token + "&ts=" + lts;
    }
   /**
     * 获取分组id
     *
     * @param fileUrl 文件地址
     * @return 分组id
     */
    public static String getGroupId(String fileUrl) {
        if (fileUrl.indexOf("/group") == 0) {
            fileUrl = fileUrl.substring(fileUrl.indexOf("/") + 1);
        } else if (fileUrl.contains("http")) {
            int index = fileUrl.indexOf("group");
            if (index != -1) {
                fileUrl = fileUrl.substring(index);
            }
        } else {
            int index = fileUrl.indexOf("group");
            if (index != -1) {
                fileUrl = fileUrl.substring(index);
            }
        }
        return fileUrl;
    } 

得到

http://192.168.56.10:8888/M00/00/00/wKg4C1tFmTWAFPKBAADdeFFxlXA240.png?token=2fd428c6acc14126239e3a7d7d1d872b&ts=153

测试

正确的token请求

错误的token请求

问题

1. 实现了文件上传,但是通过Nginx去访问文件就报错请求出现:ERROR - file: ../fastdfs-nginx-module/src/common.c errno: 13, error info: Permission denied

解决办法:

对storage的新挂载的data2(本系统新建的文件夹是data2)赋权限。执行命令 chmod -R 777 data2/ 即可,最好是777

2.fastdfs的常见错误:getStoreStorage fail, errno code: 0,getStoreStorage fail, errno code:2@TOC

解决办法:

  1. 首先看先注册中心配置的文件地址与服务器中/etc/fdfs/storage.conf的地址是否一致

2.如果以上配置正确且一致,重启tracker和重启storage

重启命令:
tracker:fdfs_trackerd /etc/fdfs/tracker.conf restart
storage:fdfs_storaged /etc/fdfs/storage.conf restart


原文章地址:
https://blog.csdn.net/z13615480737/article/details/134134293
https://blog.csdn.net/packge/article/details/126451355

posted @ 2024-06-25 18:51  快乐小洋人  阅读(162)  评论(0编辑  收藏  举报