ASP.NET Core 分布式文件上传系统

曾经做过一个学校的系统,主要用于老师上传课件和布置作业,学生学习和提交作业,当时也没考虑那么多,上传的文件全部都是放在同一个服务器上了,没想到几年过去了,这个系统还一直在用着,长时间上传的资源文件使硬盘空间吃紧了,历史数据还没法存档,由于这个契机吧,自己简单实现了一个文件分布上传的系统。下面称为 ufs。

 

一、系统架构图

 

ASP.NET Core 分布式文件上传系统

上图描述了用户上传文件和访问文件的流程走向,系统主要涉及 ufs 和下面的 node。

ufs 是 web 网站或者 app 上传的统一接口,ufs 根据配置把上传的文件分发到某个 node 上。

node 会返回上传结果给 ufs,主要是上传成功后的文件 url,ufs 收到 url 再返回给上层应用。

上层应用获取到 url 可以展示出来或者存储到数据库。

 

当用户访问资源的时候,直接从各个 node 获取。

 

当某个 node 的可用存储满了,可以从 ufs 配置中删除掉,然后加入新的 node,删除的 node 只要是服务不关闭,照样可以访问上面的文件,具体配置看下面。

 

二、ufs 配置

{
"ufs": {
"allowExts": [".txt", ".jpg", ".jpeg", ".png", ".bmp", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf"],
"limitSize": 10485760,
"accessToken": "123456",
"downstreams": [
"http://node1.ufs.timeschip.com"
    ],
"test": {
"limitSize": 10485760,
"accessToken": "abcd"
    }
  }
}

 

ufs 就是 node 的网关,提供了下面这几个功能配置:

 

  1. allowExts 数组用于配置可以上传的文件类型

  2. limitSize 限制文件上传的大小

     

  3. accessToken 访问 ufs 的令牌

     

  4. downstreams 配置下游 node 节点

 

上面配置中,和 ufs 平级的还有一个 test 节点,里面允许的子节点和 ufs 的子节点是一样的。目的是为不同的应用提供上传服务。

 

此处的“test”就是应用名称,这个名字需要和上层应用约定好,test 应用上传的时候表明是 test,就会使用配置文件中 test 的配置,如果配置文件中没有 test 这个节点配置,就会使用 ufs 节点下的默认配置。

 

这样的配置方式就像该配置文件本身(appsettings.json)的加载方式一样,会使用指定的配置覆盖默认配置,非常灵活。至于如何调用,我们后面再说。

 

三、ufs.node 配置

{
"ufsNode": {
"mimeModifiers": [
      {
"ext": ".htm3",
"type": "text/html",
"opt": "add"
      },
      {
"ext": ".mp4",
"opt": "remove"
      }
    ],
"domain": "http://node1.ufs.loogn.com",
"physicalPath": "D:/WebSite_Core/ufsnode1/upload",
"virtualPath": "/ufs",
"cachePeriod": 604800,
"enableThumbnail": true,
"thumbnailExts": [
".jpg",
".png"
    ],
"allowIPs": [
"::1",
"127.0.0.1",
"122.114.222.186"
    ]
  }
}

 

node 的配置比 ufs 要多一些,毕竟真正的存储和访问功能都在 node 上:

 

mimeModifiers 数组可以修改 node 服务的 mime 类型,每一项有三个子节点:ext 为文件后缀名,type 为映射的 ContentType, opt 是枚举可取 add、remove。

 

  • domain 为该 node 服务运行的域名,是上传文件 url 的一部分

     

  • physicalPath 为上传的物理路径,存储的本地绝对路径

  • virtualPath 为上传的虚拟路径,是上传文件 url 的一部分

     

  • cachePeriod 过期时间(秒)

     

  • enableThumbnail 是否启用缩略图功能

     

  • thumbnailExts 表示哪些文件类型可以使用缩略图功能,只能配置图片格式

     

  • allowIPs 访问白名单,即 ufs 服务的 ip 地址

 

当启用缩率图功能时,可以在 url 中加 w 和 h 参数来访问想要的缩略图:

 

  • 原图:http://node1.ufs.loogn.com/app1/2019/05/10/abc.png

     

  • 限宽 200:http://node1.ufs.loogn.com/app1/2019/05/10/abc.png?w=200

     

  • 限高 200:http://node1.ufs.loogn.com/app1/2019/05/10/abc.png?h=200

     

  • 限宽高 100*200:http://node1.ufs.loogn.com/app1/2019/05/10/abc.png?w=100&h=200

 

所有的压缩都是等比的,图片不会变形,不管参数怎样,图片也不会放大。

 

从 allowIPs 配置可以看出,应用层访问 ufs 是用过 accessToken 来验证的,而 ufs 访问 node 是通过在 node 中配置允许的 ip 地址来实现的。

 

ASP.NET Core 分布式文件上传系统

 

四、应用层调用

 

由于公开的是 http接口,所以任何支撑 Http 的语言都可以使用。

static async Task<string> UploadFile(string filePath)
{
    HttpClient httpClient = new HttpClient();
    httpClient.DefaultRequestHeaders.Add("accesstoken", "abcd");
    httpClient.DefaultRequestHeaders.Add("app", "test");

var buffer = File.ReadAllBytes(filePath);
    ByteArrayContent byteArray = new ByteArrayContent(buffer);
    byteArray.Headers.Add("ext", Path.GetExtension(filePath));
var response = await httpClient.PostAsync("http://ufs.loogn.com/uploadfile", byteArray);
var result = await response.Content.ReadAsStringAsync();
return result;
}

 

http 请求头部需要传输三个参数:

 

  1. accesstoken 为访问 ufs 的令牌,对用 ufs 中的配置

     

  2. app 为指定 app 的名称,除了和 ufs 服务中选择配置相关,node 服务也会在 physicalPath 目录下建立 app 同名目录,用来存放这个应用上传的文件,如果没有这个参数,node 会放入 default 文件夹

     

  3. ext 为上传文件的后缀名,注意,是带.的(比如:.jpg 而不是 jpg)

 

文件内容通过请求体 POST 到 ufs 公开上传地址/uploadfile,响应的字符串是 json 格式,如下:

{"success":true, "msg":"", "fileUrl":"http://node1.ufs.loogn.com/app1/2019/05/10/abc.png"}

 

如果上传失败,success 为 false,msg 中有错误信息。

 

五、项目地址

 

源码:https://gitee.com/loogn/ufs


  转自:loogn

cnblogs.com/loogn/p/10845179.html

© 版权声明

☆ END ☆
喜欢就点个赞吧
点赞0 分享
图片正在生成中,请稍后...