高性能分布式文件存储及文件下载解决方案-基于Nginx+Fast

2019-10-11  本文已影响0人  李小磊_0867

当前服务中有大量的文件,包括图书、短文等,同时也包括音频、视频、图片等资源。其存储及下载方案是需要仔细思考。一方面满足大量文件存储、后续扩容等基本需求;另一方面还要能够支持高性能下载,解放服务器压力;同时还要考虑文档地址的安全性,防盗链,以及检查用户的下载权限等。

本系统的设计主要为了解决以下几个问题:

系统架构

架构图

系统整体架构参见上图,描述了本系统的所有部署模块、结构,以及对文档的下载过程做了详细描述。从架构图上看该方案主要分为以下几个模块:

逻辑处理流程


上图流程描述了文档存储的处理流程,对照系统架构中,主要操作为:文档映射服务、内容管理系统、FastDFS等三个模块。

上述流程,就是一个普通的上传流程,唯一区别是增加了文档映射服务模块。在该模块中,主要存储了两种信息:

  1. 文件在FastDFS中的位置信息
  2. 用户访问该文件的URL,比如https://www.xx.com/storage/748/startjava.epub,该URL可以是生成的短Url(/storage/beNvds34sd) ;URL也可能是资源的标识b20190819001;总之通过该访问URL能够映射到FastDFS的位置信息

上述流程中,对于文件存储主要依赖于FastDFS,而对于上传的并发、内存等需求,未发生改变,可通过部署分节点提高上传性能。对于读多写少的系统而言(通常更多的大文件仍然是通过后台分步存储),高性能的读取对于性能的提高效果更为显著。

对于文件的读取,主要用到的模块为:

以上步骤为下载文件的整体流程,为了实现鉴权、Nginx高性能分发文件,需要对Nginx进行下述配置:

具体部署方案

Nginx配置

http {
    include       mime.types;
    default_type  application/octet-stream;
    proxy_set_header      Host $host:$server_port;
    # 远程IP
    proxy_set_header      X-Real-IP $remote_addr;
    proxy_set_header      X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header      X-Forwarded-Proto  $scheme;
    
    proxy_set_header      X-Sendfile on;
    sendfile        on;
    
    server {
        listen       9001;
        server_name  localhost;
        location /M00 {
           internal;
           root /home/storage/fdfs/data/;
           ngx_fastdfs_module;
        }
        
        location / {
           root html;
           if ($request_uri ~ (.*)/d/) {
                rewrite ^.*/d/(.*) /$1 break;
                proxy_pass  http://http_t;
          }
        }
    }
}

以上配置为基础配置。部分说明:

proxy_set_header      X-Sendfile on; # 对转发请求,添加X-Sendfile节点信息
sendfile        on;  #开启nginx文件分发

location /M00 部分,为FastDFS的配置,其中添加了internal,保证该代理只能通过内部转发请求。root节点配置的是FastDFS的文件存储位置。

后一个包含/d/的节点配置,模拟了文件映射服务的配置。

文件映射处理逻辑

    @GetMapping("/t")
    public void download(HttpServletResponse response, @RequestHeader(value = "X-Sendfile", required = false) String useXSend) {
        if ("on".equalsIgnoreCase(useXSend)) {
            // nginx分发下载
            response.setHeader("Content-Disposition", "attachment;filename=test.epub");
            response.setHeader("X-Accel-Redirect", "/M00/00/00/wKhxkF1wLL6AGsQVABFbpT1QNps669.epub");
            response.setHeader("X-Accel-Buffering", "yes");
        } else {
            // 容器下载
        }
    }

上述示例程序中,只描述了Nginx分发下载的过程,对于容器下载,就是普通的读取文件,并写数据流到客户端。通过X-Sendfile控制是走容器下载,还是走Nginx下载。另外Nginx和容器都可以支持断点续传,后续会描述Nginx的断点续传功能。

上一篇 下一篇

猜你喜欢

热点阅读