You are on page 1of 5

应该具备的功能:

1. 能在 Web 页面上列出已经备份在服务器上的文件, 呈现给用户的应该是文件的源目录树格式.


2. 应能列出同一文件的多个备份版本
3. 应该列出每个文件的实际大小, 备份时间, 以及所在的备份集信息, 如: 用户自定义的说明.
4. 应该允许用户恢复单独的一个檔而不是完全的备份集, 如果备份集很大, 应该只传输该文件而不是整个
备份集到用户机器。
5. 应该允许用户删除整个备份集以减少所占空间, 或者删除单独的一个或几个文件
6. 应该允许用户按备份集进行恢复
7. 用户提交任务后, 应该在任务列表中看到该任务的进度或状态, 已经该任务的备份日志
8. 在目录树视图外, 应该能呈现给用户备份任务文件视图, 也就是列出每个备份任务所备份的文件; 对于
自动调度进行的备份, 由于用户指定所要备份的文件与实际备份启动时间可能相差较久, 需备份的文
件可能在备份时已经不存在了, 对于这些文件, Web 视图上应该显示该文件已丢失, 也就是视图上始终
显示用户指定的完整的备份集, 通过不同颜色或其它手段告诉用户该文件已经不存在或者已经被用户
手工删除。
9. 提供选项以满足用户只想看到存在的文件, 而不想看到丢失或自己删除的文件的要求
10. 对于用户的删除等操作, 需要记录日志; 以防止用户忘记自己的操作而认为文件丢失责任在运营商。
11. 应该能够显示已备份文件所占空间大小以及用户剩余空间的大小。
12. 应该支持用户一个账号备份多台机器的文件, 只要不超过其配额。 在 Web 接口上应该体现出档属于哪
个机器: 也就是文件树视图应该以机器节点为顶层节点。
13. 文件恢复应该允许用户指定恢复目录, 或恢复到原路径; 对于恢复其它机器上的文件, 必须要求其选择
恢复目录。
14. 在用户手工启动备份与自动调度恰好同时运行时, 备份操作可以排队; 但需要将任务信息并发更新到服
务端尔后再排队, 这样用户可以在任务列表中看到所有的任务.
15. 需要支持在未连接的情况下, 服务端能够主动发通知消息到客户端.
Web 页面 Web server

Notice server

DB Agent + DB server
Task Server

Media Server
Agent

备份流程:
1. 发起任务
Agent+根据调度设定自动发起: 线程 1 等待调度时机, 一旦到来为每个任务生成一个唯一的任务记录 ,
包含唯一客户端任务 ID, 任务状态, 任务类型, 以及其它相关信息, 任务状态初始化为 1. 如果操作失败,
不做任何操作. 若成功, 唤醒线程 2, 线程 2 执行以下操作:
1. 主动连接 Task Server, 将发起任务请求, 将客户端 TaskID, 客户端调度表更新序号 USN 发给 Task
Server, 将收到的 USN 同服务端调度表 USN 对比, 如果不等, 返回错误码指示 Agent+ 进行调度表
同步.若匹配, Task Server 生成一条任务记录, 包含字段: 唯一服务端 TaskID, 客户端 TaskID, 任务
状态, 初始化服务端 TaskID 和客户端 TaskID 字段, 任务状态初始化为 1. 将 USN 以及服务端
TaskID 返回给 Agent +。
2. 如果第一步返回需调度表同步, 则进行同步, 然后根据新调度表决定本次运行是否终止, 如果继续
运行, 则返回第一步.
3. 如果根据新调度表, 本次运行可以终止, 则对任务设置取消标志, 如果设置也不成功, 只能循环设
了, 具体实现多样, 但不应该类似 while(1){if(set_cancel_flag()){break;}} 这种样子; (为了代码好维
护, 取消操作全部由线程 3 负责, 因此这里不应该自己取消)
4. 如果不需要同步调度表, 或者根据新调度表可以继续运行, Agent+ 读取本地保存的调度表, 根据里
面信息扫描磁盘, 建立需要备份的文件列表.
5. 将备份文件列表保存在本地数据库中, 如果已经存在相应备份文件列表, 先删除这些记录. 更新任
务状态为 2. 如果任一失败, 转到第 7 步
6. 唤醒线程 3.
7. 视当前有无排队的下一个任务以及本任务成功否, 或转到下一个任务, 或重试本任务, 或睡眠等待
下次调度。

Web 页面手工发起, 通过 “Web 页面发起任务通知本地客户端机制” 的描述, 通知 Agent+, Agent+启动


一个线程(线程 4)为其服务, 线程 4 为每个任务生成一个唯一的任务记录, 包含唯一客户端 TaskID, 任
务状态, 任务类型, 以及其它相关信息, 任务状态初始化为 1. 如果操作失败, 通知 Web 页面, 任务结束.
若成功:
1. Agent+ 根据用户指定的备份文件列表, 扫描本地磁盘. 并将备份文件列表保存到数据库. 如果保存
失败, 设置任务取消标志, 通知 Web 页面.
2. 主动连接 Task Server, 将客户端任务 ID, 无效 USN 发给服务器, 服务器生成一条任务记录, 包含字
段: 唯一服务端 TaskID, 客户端 TaskID, 任务状态, 初始化服务端 TaskID 和客户端 TaskID 字段,任
务状态初始化为 1. 如果操作失败, Task Server 返给 Agent+ 错误码. 否则, Task Server 将 USN 以及
服务端 TaskID 返回给客户端。
3. Agent+ 接收 Task Server 回应, 记录服务端 TaskID, 同时更新任务状态为 2
4. 唤醒线程 3.
5. 通知 Web 页面.

2. 备份(线程 3)
线程 3 在任务表上轮询, 对其中任何未完成的任务进行检查
 设置了取消标志的, 进行取消
 如果如果任务状态为 1, 手工发起, 服务端 TaskID 为空的, 检查是否有与 Web 页通信的线程
存在, 如果存在不作任何操作, 否则, 向 Task Server 提交取消该任务请求.
 如果任务状态为 2, 获取任务运行次数, 如果是手工任务且运行次数 >= 1, 则将本地文件列
表内的信息更新到服务器, 如果 Task Server 返回成功消息, 删除本任务记录 (及关联的
文件记录) 。 如果删除没成功, 不作任何操作, 迟早会重试。
 如果任务状态为 2, 获取任务运行次数, 如果是调度任务 或 手工任务且运行次数 0, 运行次
数+1, 如果记录运行次数失败, 本次运行终止, 线程重新在任务表轮询; 否则, 将该任务文
件列表中 Status 字段表明未完成的文件发给 Agent。 对于 Status 表明已完成的同步到服务
器, 而后删除同步完成的文件记录。 如果已同步而删除失败的, 只好重新同步一次,
Task Server 需要处理这种情况; 如果有的记录 Status 表明未完成, 则需要 Task Server 直
接询问 Media Server 是否真没有完成, 也有可能是客户端记录完成标志时失败了。
 完成所有任务后, 进入休眠状态

1. 建立同 Agent 的连接, 按 Agent 现有协议启动备份并发送需备份的文件列表


2. 持续进行状态查询, Agent 需要支持以下新需求: 返回已处理的文件列表及其文件大小, 对于备份
失败的文件, 报告错误原因, Agent+ 在本地记录完成标志及错误原因, 如果记录出错, 不做任
何处理。
3. 将完成的文件记录实时更新到服务器, 如果实时更新到服务器, 更新成功后, 删除本文件记
录, 或者等整个任务结束后进行批更新(更新成功的文件记录进行删除, 如果删除失败, 不
作任何操作) 。
4. 如果备份结束, 向 Task Server 发送完成消息, 删除任务记录(及关联的文件记录), 如果中
间出错, 例如备份过程被中断, 或者文件列表更新到服务器未成功, 不作任何处理, 线程下
一次轮询时会做处理。

Web 页面发起任务通知本地客户端机制
1. 客户端周期性连接 web 服务器获取存储在 Web Server 上的若干个页面及其版本号
2. Web 页首页内嵌隐藏 Iframe 元素, 内容为 Web Server 一个在加载时执行 JavaScript 的页面, 该页面获取
当前网站版本, 并写入客户端 JavaScript 中, 当该脚本执行时, 可以将版本发给客户端监听埠, 客户端获
取后与自己保存在本地的版本比对, 若不相符, 立即更新。
3. 客户端获取的页面要包含约定的元素
4. 当用户在 Web 上启动备份时, 将请求发给本地客户端, 本地客户端则根据请求的参数, 使用从服务器获
取的页面进行相应.
5. 这些页面内嵌不可见 Iframe, 如此客户端可以通过向 Iframe 返回脚本方式进行, 返回的脚本在执行时进
行可见接口更新.
6. 由于这些页面都是同域页面, 因此可以绕过浏览器安全限制.

恢复步骤:
文件恢复比较简单, 所需要的数据库操作只是生成一条任务记录, 然后由客户端不断将进度信息更新
到该记录中, 由 Web 页面不断进行刷新显示进度信息即可. 如果失败, 自然也会显示失败信息. 恢复操
作也没必要进行失败后重试.
由于备份操作是由客户端请求服务端增加的任务记录, 恢复操作也让其请求以保持一致。

磁盘空间管理:
1. 用户从 Web 页发出请求, 经 Web Server 到 DB Server , DB Server 请求 Media Server 分配空间, 并
将分配的空间记录于用户的账号表中.
2. 每个文件自己大小记录于自己的记录中, 这样可以向用户显示已用/剩余空间大小

Notice Server 作用:


1. 作为服务器, 接收客户端周期性 UDP 包以提供服务端主动连接客户端所需要的 NAT 打洞信息
2. 主动连接到 DB Server, 当用户在 Web 页面上更改了调度设置时, Web Server 通过 DB Server 将数
据存入时, DB Server 可以发起通知给 Notice Server, 后者发起通知给客户端, 从而使客户端主动
连接服务器进行数据同步.
3. 如果服务端 IP 地址变动, 而且没有其它复位位手段 , 则可以让服务端周期性发自己 IP 地址给
Notice Server, 而 Notice Server 可以通知客户端。

Media Server:
1. 需要实现现有几个与 Agent 通信的命令
2. 需要实现 Task Server 询问某个文件是否存在等信息的请求。
3. 需要实现单独传输某一个文件或删除某一个文件, 而该文件可能和其它文件打包在同一个包中,
作为个人用户, 很可能有这个需求。

DB Server:
DB Server 实现为一个单独的服务程序, 以提供以下方面便利:
1. 数据库采用 sqlite, 这是一个基于本地访问的数据库, 而单独在之上实现一个服务器, 则可以实现
网络访问, 从而将分散在各个机器上的数据库文件集中起来.
2. 与 Media Server, Notice Server 建立连接, 从而在发生某些事情比如 Web Server 更新了某记录时可
以主动通知这些程序。

用户一个账号备份多台机器数据支持:
1. 客户端可以为每台机器生成一个唯一的标识: 比如根据网卡物理位址或 CPU ID 生成的标识
2. 客户端发起备份任务时, 将该唯一标识放在请求中发给服务端, 并记录于数据库中
3. 客户端建立备份调度时, 用户页面由客户端生成, 这样客户端就可以将唯一标识附在 Web 请求中发给
Web Server. 用户页面必须由客户端生成, 因为建立调度要求必须访问本地目录, 这个不是 HTML + Js
能够做到的, 只有靠客户端以提供这种能力。
4. 客户端数据库与服务器同步数据时, 客户端只将与自己标识符合的更新记录进行同步。
数据库:
1. 任务表
字段名称 类型 长度 允许空 说明
Server TaskID int 4 否 唯一字段, 服务器上此为自增字段
Client TaskID int 4 否 唯一字段, 客户端上此为自增字段, 在服务器上需要
和 ClientID 合并可能才会唯一
Task State Int 4 否 任务状态
Task Type char 1 否 任务类型(0, 自动调度; 1, 手工发起)
Start Time DateTime 否 启动时间
End Time DateTime 否 停止时间
ClientID char 24 否 客户端 ID, 用以识别一个账号多台机器情况
Comment varchar 512 是 任务说明, 用户手工发起时, 可能想创建一个说明

2. 用户表
字段名称 类型 长度 允许空 说明
UserID char 24 否 唯一字段, 用户账号
PassWD char 16 否 密码
Quota Int 4 否 空间配额 (KB)
USN int 4 否 自动备份模板表更新序号
… 其余信息, email 之类的

3. 调度模板表
字段名称 类型 长度 允许空 说明
TemplateID int 4 否 唯一字段, 范本 ID, 在服务端为自增字段
ClientID char 24 否 客户端 ID, 用以识别一个账号多台机器情况
FileList text 否 文件列表
RunTime Time 否 启动时间
Interval int 否 启动间隔 (小时)

4. 日志表
字段名称 类型 长度 允许空 说明
ID int 4 否 自增字段
log varchar 512 否 日志内容
TaskID int 4 否 Server TaskID

5. 文件表
字段名称 类型 长度 允许空 说明
TaskID int 4 否 在客户端是 Client TaskID, 服务端是 Server TaskID
pathname varchar 512 否 原文件全路径
Status int 4 是 文件状态: 已备份/备份未完成/已被用户删除
Size Int 4 否 文件大小 (KB)
error varchar 256 否 如果备份未成功, 原因

You might also like