简介
本文件为 DouPHP 的“备份存储”方案文档,围绕本地存储策略、云存储集成扩展点、异地备份策略、加密存储、生命周期管理(清理与容量预警)、性能优化(并发上传、分片传输、缓存)以及访问控制与审计日志进行系统化说明。内容基于仓库中现有的备份控制器与服务、文件系统抽象与本地驱动实现、以及云配置入口进行分析与扩展建议。
项目结构
DouPHP 的备份能力由后台路由、控制器、服务层与文件系统抽象共同构成:
- 路由层:声明式路由将 /backup 请求分发到 BackupController。
- 控制器层:BackupController 负责接收请求、调用服务并返回统一响应。
- 服务层:BackupService 实现分卷 SQL 导出、ZIP 打包、导入还原、删除与流式下载等核心逻辑。
- 存储层:通过 FilesystemManager 与 LocalAdapter 提供本地磁盘读写;同时预留 extend 扩展点以接入第三方云存储驱动。
- 配置层:config/file.php 定义默认磁盘与上传策略;config/cloud.php 提供云服务 API 基础地址(用于云端交互)。
graph TB
subgraph "后台"
R["路由 backup.php"]
C["BackupController.php"]
S["BackupService.php"]
end
subgraph "存储抽象"
FM["FilesystemManager.php"]
LA["LocalAdapter.php"]
end
subgraph "配置"
CF["config/file.php"]
CC["config/cloud.php"]
end
R --> C --> S
S --> FM
FM --> LA
C --> CF
C --> CC
核心组件
- 路由与控制器
- 路由将 /backup 映射到 BackupController,支持 index、restore、down、backup、import、destroy 等操作。
- 控制器委托 BackupService 执行业务,并通过 message() 统一返回消息、跳转与二次确认 URL。
- 备份服务
- 构建表清单、执行分卷 SQL 导出、可选 ZIP 打包 images 目录、导入还原、删除备份、流式下载。
- 使用 Zip 工具生成包,并在解压时采用白名单与黑名单限制条目,防止覆盖危险路径或可执行文件。
- 写入审计日志记录备份、恢复、删除操作。
- 文件系统抽象
- FilesystemManager 解析 disk 名与配置,构造 Disk 实例;当前内置 local 驱动,并提供 extend 扩展点注册自定义驱动。
- LocalAdapter 实现本地磁盘读写、目录创建、URL 生成与安全路径校验,拒绝越界与根目录删除。
- 配置
- config/file.php 定义默认磁盘、上传上限、允许扩展名、图片质量与缩略图目录等。
- config/cloud.php 提供云服务 API 基础地址,便于后续与云端服务对接。
架构总览
下图展示了从后台请求到备份数据落盘与下载的完整链路,包括分卷导出、ZIP 打包、导入还原与审计日志。
sequenceDiagram
participant Admin as "管理员"
participant Route as "路由 backup.php"
participant Ctrl as "BackupController.php"
participant Svc as "BackupService.php"
participant FS as "FilesystemManager.php"
participant Loc as "LocalAdapter.php"
participant DB as "数据库"
participant Zip as "Zip工具"
Admin->>Route : 访问 /backup
Route->>Ctrl : 分发到 BackupController
Ctrl->>Svc : runBackup(选择表/分卷大小/是否含资源)
Svc->>DB : 查询表结构与数据(分卷 LIMIT)
DB-->>Svc : SQL片段
Svc->>Loc : 写入 storage/backup/*.sql
alt 包含附件
Svc->>Zip : 打包 *.sql + images
Zip-->>Svc : 生成 .zip
end
Svc->>Admin : 返回消息/续传URL/超时
Admin->>Ctrl : 导入/下载/删除
Ctrl->>Svc : runImport/streamDownload/runDelete
Svc->>FS : 读取/删除备份文件
Svc->>Admin : 审计日志记录
详细组件分析
备份控制器与路由
- 路由集中声明 backup 模块的 GET/ANY/DELETE 动作,确保备份、导入、下载、删除等操作的统一入口。
- 控制器仅做参数透传与响应组装,业务集中在服务层,便于测试与扩展。
备份服务(分卷导出、ZIP 打包、导入、删除、下载)
- 分卷导出:按表循环导出,累计长度达到分卷阈值后输出下一分卷,支持续传(startfrom/volid)。
- ZIP 打包:当选择包含资源时,将 SQL 分卷与站点 images 目录打包为 zip,完成后清理中间文件。
- 导入还原:支持 zip 解压与多分卷顺序导入,解压时使用白名单与黑名单严格限制条目类型。
- 删除备份:支持主文件与同前缀分卷批量删除,二次确认后执行并写审计日志。
- 流式下载:直接设置响应头并以固定块大小流式输出,避免大文件内存占用。
flowchart TD
Start(["开始备份"]) --> CheckTables["校验选择的表/文件名"]
CheckTables --> DumpLoop{"是否还有未导出的表?"}
DumpLoop --> |是| DumpTable["导出表结构与数据<br/>累计长度达阈值则切分"]
DumpTable --> WriteSQL["写入 storage/backup/*.sql"]
WriteSQL --> DumpLoop
DumpLoop --> |否| PackCheck{"是否包含附件?"}
PackCheck --> |是| ZipPack["Zip::create 打包 SQL + images"]
PackCheck --> |否| Done["完成"]
ZipPack --> Cleanup["清理中间分卷/单文件"]
Cleanup --> Done
文件系统与本地存储
- FilesystemManager:解析 disk 名与配置,构造 Disk;当前内置 local 驱动,并提供 extend(driverName, factory) 扩展点以注册自定义驱动(如 OSS/S3)。
- LocalAdapter:实现本地磁盘读写、目录创建、URL 生成与安全路径校验;拒绝删除磁盘根目录,递归删除时逐条校验 realpath 防止越界。
classDiagram
class FilesystemManager {
+disk(name) Disk
+build(relativeRoot, overrides) Disk
+extend(driverName, factory) void
+getDiskConfig(name) array
}
class Disk {
<<object>>
}
class LocalAdapter {
+read(path) string|false
+write(path, contents) bool
+delete(path) bool
+copy(from,to) bool
+move(from,to) bool
+size(path) int|false
+lastModified(path) int|false
+listContents(directory, recursive) array
+createDirectory(directory) bool
+deleteDirectory(directory) bool
+publicUrl(path) string
+absolutePath(path) string
}
FilesystemManager --> Disk : "构造"
Disk --> LocalAdapter : "封装适配器"
云存储集成方案(扩展点设计)
- 扩展机制:通过 FilesystemManager::extend('oss'|'s3', $factory) 注册自定义驱动工厂,返回实现 FilesystemAdapter 的适配器对象。
- 配置方式:在 config/file.php 的 filesystems.disks 中新增云磁盘项(driver=oss/s3),并传入对应凭证与桶名等参数。
- 行为一致性:无论后端是本地还是云存储,上层均通过 Storage/Disk 接口一致调用,无需改动备份流程。
- 云平台示例:阿里云 OSS、腾讯云 COS、AWS S3 均可通过 SDK 实现适配器,遵循相同接口契约。
异地备份策略
- 目标:将备份副本同步至不同地理位置的云存储,提升容灾能力。
- 实现建议:
- 在备份成功后,触发异步任务将本地 storage/backup/*.sql/.zip 复制到多个云存储桶(不同区域)。
- 对每个副本建立独立的生命周期规则(保留期、归档/冷存储)。
- 定期校验副本完整性(校验和比对)。
- 注意:该策略属于部署侧增强,可在现有备份流程完成后追加。
加密存储(传输与静态数据)
- 传输加密:所有与云存储的通信应强制 HTTPS/TLS;若自建网关,需启用 TLS 终止与证书轮换。
- 静态数据加密:
- 云侧:开启服务端加密(SSE-KMS/SSE-C)或客户端加密后再上传。
- 本地侧:可对敏感备份文件进行磁盘级加密或文件级加密(如 openssl 对称加密),但需妥善管理密钥。
- 密钥管理:建议使用密钥管理服务(KMS/HSM),避免硬编码密钥。
备份生命周期管理
- 自动清理过期备份:
- 本地:定时任务扫描 storage/backup,删除超过保留期的文件。
- 云存储:利用对象存储的生命周期规则自动归档或删除。
- 存储空间监控与容量预警:
- 监控本地磁盘使用率与云桶容量,设置阈值告警。
- 在备份前检查可用空间,不足时中止并告警。
- 版本与命名:
- 保持统一的命名规范(如 AUTO+时间戳),便于识别与清理。
备份存储的性能优化
- 并发上传:
- 云存储:使用 SDK 提供的并发上传/分片上传能力,提高大文件上传吞吐。
- 本地:避免在同一时刻大量并发写入同一目录导致锁竞争。
- 分片传输:
- 针对超大备份文件,采用分片上传与断点续传,降低失败重试成本。
- 缓存策略:
- 对频繁读取的元数据(如表清单)进行短期缓存,减少数据库压力。
- 下载端可使用浏览器缓存(Accept-Ranges)提升体验。
访问控制与审计日志
- 访问控制:
- 备份相关接口仅限已登录管理员访问;建议结合权限中间件与 CSRF 保护。
- 下载接口需鉴权,避免匿名访问备份文件。
- 审计日志:
- 备份、恢复、删除操作均会记录审计日志,便于追溯。
- 建议将审计日志集中收集与分析,设置异常操作告警。
依赖关系分析
- 控制器依赖服务:BackupController 仅做路由与响应包装,核心逻辑在 BackupService。
- 服务依赖数据库与文件系统:备份导出依赖数据库查询与写入;导入依赖 SQL 执行;下载依赖文件读取。
- 文件系统抽象解耦存储实现:通过 FilesystemManager 与 LocalAdapter 屏蔽底层差异,便于扩展云存储。
- 配置驱动行为:config/file.php 决定默认磁盘与上传策略;config/cloud.php 提供云服务 API 基础地址。
graph LR
Ctrl["BackupController"] --> Svc["BackupService"]
Svc --> DB["数据库"]
Svc --> FS["FilesystemManager"]
FS --> LA["LocalAdapter"]
Ctrl --> CFG["config/file.php"]
Ctrl --> CLD["config/cloud.php"]
性能考虑
- 分卷导出:通过合理设置分卷大小,平衡单次处理耗时与内存占用。
- 流式下载:使用固定块大小输出,避免一次性加载大文件到内存。
- 并发与限流:在高并发场景下,对备份与导入操作进行队列化与限流,避免阻塞前台请求。
- I/O 优化:将备份目录置于高性能磁盘;云存储侧启用 CDN 加速下载。
故障排查指南
- 备份失败
- 检查 storage/backup 目录是否可写;查看错误信息中的权限提示。
- 确认数据库字符集与版本兼容性(服务层已处理零日期与字符集)。
- 导入失败
- 校验备份文件完整性;确认分卷顺序正确。
- 检查 SQL 模式(严格模式)与数据类型匹配。
- 下载异常
- 确认响应头设置与网络代理是否支持断点续传。
- 云存储扩展问题
- 核对驱动扩展是否成功注册;检查凭证与桶配置。
- 使用最小化用例验证适配器读写能力。
结论
DouPHP 的备份系统以清晰的控制器-服务分层为基础,借助文件系统抽象实现了本地存储的安全与可扩展性。通过 extend 扩展点可无缝接入主流云存储服务,配合异地备份、加密存储、生命周期管理与性能优化,形成完整的备份存储体系。建议在部署阶段完善自动化清理、容量监控与告警,确保备份数据的可靠性与可恢复性。
附录
- 关键路径参考
- 备份入口与动作:backup.php
- 控制器与响应:BackupController.php
- 备份核心逻辑:BackupService.php
- 文件系统抽象与本地驱动:FilesystemManager.php、LocalAdapter.php
- 存储与上传配置:file.php
- 云服务 API 基础地址:cloud.php