一个B/S的文件处理工具设计

内容纲要

一个B/S的文件处理工具设计

一个很简单的文件处理系统: 用户上传文件到系统中,然后选择处理工具进行处理,处理完成后下载处理后的文件。

用户可以不用登录直接使用系统进行文件处理。

需求分析

用户

  1. 系统要支持匿名用户,因为用户不需要登录。那是否需要跟踪匿名用户?这个根据需求而定,如果需要跟踪,那么Cookie是首选,服务器创建一个Cookie,前端也不用做任何处理,用户清除了缓存或者禁用了Cookie就只能想其他方式,比如:浏览器指纹。

文件上传

用户需要上传文件到服务器,然后再处理文件。

我们需要提供一个接口或者服务来处理文件上传。上传的文件存储到哪儿?我们有几个可选项:

文件处理

用户上传完文件以后需要手动选择文件处理的方式:拆分,组合等等。选择完成后提交文件处理请求,然后等待文件处理完成。

这个过程需要做成异步,因为用户上传的文件可能会比较大,处理比较耗时,一个HTTP请求接口完成创建任务和等待任务处理完成可能会有问题。那么我们就可以把任务拆分成以下几个阶段:

  1. 任务提交
  2. 任务状态查询
  3. 任务结果获取

系统架构设计

基于以上的分析,我可以得到以下内容:

  1. 用户
  2. 文件
  3. 异步
  4. 处理
  5. 结果

那么我们的模块会有:

  1. 用户模块:用来管理匿名/登录用户
  2. 文件模块:用来接受用户上传的文件进行存储;接受文件处理结果进行存储
  3. 任务模块:接受用户的文件处理请求并处理文件;向用户返回文件处理结果

以上是我们纯需求而得到的模块同时模块化是架构设计的第一个需要考虑的东西,那么我们涉及的时候还要考虑其他方面,这些方面包括:

  1. 可扩展性: 系统应该能够快速并且很容易的进行伸缩以满足业务的变化。比如:当用户多且处理文件比较多的时候系统应该可以很快的进行横向扩展;相反,当用户减少和文件处理减少时系统应该可以进行缩容来节省成本。
  2. 高可用性: 系统出了故障应该可以进行故障转移或者进行快速恢复。比如:文件处理失败了系统应该可以感知到失败,如果失败的原因是因为系统组件的问题,那么应该可以将文件处理转移到没有问题的系统组件中;又比如:文件处理挂了应该可以很快的感知并恢复。
  3. 安全性:系统应该保证数据的安全性,防止未经授权的访问。比如:用户上传的文件其他人应该是不能访问和下载的,同时用户创建的任务其他用户业务也是不能获取状态的。
  4. 高性能:系统应该有很好的性能,能弄够在高并发情况下快速响应并处理请求。比如:很多用户请求处理文件,那么每个用户的文件应该可以很快的帮他处理完成;又比如:一个用户上传了很大的文件,那么系统应该也要使用算法进行快速处理并返回处理结果。
  5. 简单:系统应该在满足业务的情况下尽可能的简单,这样可以降低系统的复杂度,使开发人员能够很简单的开发和进行维护。比如:你设计了一个超级复杂的东西,开发人员看了以后无从下手或者后期维护的人也感觉很无力也不行。
  6. 可测试性:系统应该比较容易进行测试和验证。可测试性应该包括:单元测试,集成测试,压力测试和性能测试,并且各个模块可以单独进行这些测试。

模块设计

上面我们已经整理了3个模块,用户,文件和任务。我们再细化一下:
用户模块会简单一些,无法就是匿名用户和登录用户的认证授权和管理;
文件模块我们就要考虑到以上几个关于架构设计的方面了。既然涉及到文件,那么第一想到的就是上传下载涉及到的带宽问题,其次就是存储问题了。带宽问题是第一要解决的问题,因为要满足用户快速上传和下载,那么需要很高的带宽的同事还需要考虑使用CDN。还可以考虑将上传和下载全部使用基础设施来解决,比如:使用云上提供的文件存储,上传和下载都可以交给云上的文件存储来搞定,业务模块只负责认证授权和文件存储管理。
任务模块可以进行拆分:任务调度和任务执行。这个拆分也是比较经典的一种拆分方式了。
还有一个模块不能忽略:任务状态存储。状态存储有几个选择:存储到任务模块。存储到外部:Redis,zookeeper, redis,MySQL, PostgreSQL, MySQL, etc.

来设计几个版本的架构

架构图v1

file

这个版本架构主要组件:

  1. File Server
  2. Task Scheduler
  3. Task Executor
  4. CDN

这个版本的模块化做的不错,实现也特别简单,同时也考虑了各个地区用户文件访问速度。
问题:

  1. File Server的带宽问题。用户上传和下载都由File Server负责,那么File Server的带宽和I/O都会成为瓶颈,一般最先体现的点是带宽。
  2. 任务状态存储问题。这个版本任务状态由Task Scheduler存储在本地,那么在进行横向扩展式需要再反向代理端Sticky。

架构图v2

file

这个版本继承了V1的设计,同时引入了OSS解决了File Server带宽和I/O瓶颈。
这个版本依然没有解决任务状态存储问题。

架构图v3

file

这个版本继承了V2的设计,同时引入了一个Registry来解决任务状态存储问题。File Server只充当认证授权和文件管理工作。但是这个版本架构同时引入了复杂性。 ==,这里好像是少了一个用户模块,同时安全也没有做任何处理,那么匿名用户上传的私密问题随意被人访问岂不是又很大的问题。

架构V4

file

这个版本引入了Auth(Authentication&Authorization)模块来解决安全性问题。

用例图

Plantuml :

@startuml
left to right direction
skinparam packageStyle rectangle
actor 用户 as User
actor "任务执行器" as TaskExecutor
actor "任务调度器" as TaskScheduler
actor "文件服务器" as FileServer
rectangle "系统" {
    usecase "注册任务执行器" as UC1
    usecase "上传文件" as UC2
    usecase "提交处理任务" as UC3
    usecase "分配任务" as UC4
    usecase "下载文件" as UC5
    usecase "执行任务" as UC6
    usecase "上传处理结果" as UC7
    usecase "轮询任务状态" as UC8
    usecase "下载结果文件" as UC9

    User --> UC2 : 上传文件并获取Id
    User --> UC3 : 提交含文件Id的任务
    User --> UC8 : 轮询任务状态
    User --> UC9 : 下载处理结果

    TaskExecutor --> UC1 : 注册为可接受任务
    TaskExecutor --> UC5 : 接受分配的任务
    TaskExecutor --> UC6 : 处理文件
    TaskExecutor --> UC7 : 上传处理结果

    TaskScheduler --> UC4 : 选择TaskExecutor并分发任务
}
FileServer --> UC2 : 提供文件上传
FileServer --> UC5 : 提供文件下载
FileServer --> UC7 : 接收上传的结果
@enduml

file

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部