Files
SKYMirror 84df9996cb
CI 测试 / go vet + go test (push) Successful in 49s
26.9:版本号统一 + CI 精简 + 前端产物重建
- 全项目版本号统一:v3.x 迭代号(26.9/26.9/26.9/26.9 及裸 v2/v3)→ 26.9,
  覆盖 Go 注释 / 文档 / openapi.yaml / README×4 / 前端源码(80+ 处)
- v31_test.go 更名 custom_code_test.go;TestV2AccessorDefaults → TestKVAccessorDefaults
- docs/api/00-overview.md 更新日志合并为单条 26.9 条目(修复错位拼接)
- .goreleaser.yaml 头部注释与实际一致(Pro 2.18.1 / GITEA_TOKEN / semver tag 要求)
- CI:release-image.yml → ci.yml,仅保留 vet+test 门禁;
  镜像发布移交 GoReleaser Pro(原 build-push 的 tag 校验与 26.9 版本方案冲突,历史 9 次失败)
- 前端重建:server/web/dist 与 web-embed 同步(docs 文案嵌入更新)
2026-09-08 03:16:51 +08:00

6.2 KiB
Raw Permalink Blame History

存储引擎配置

存储引擎只支持三种:本地磁盘 / S3 / WebDAV,由进程级环境变量 FCB_STORAGE_ENGINE 选择。 引擎与引擎相关配置在启动时一次性读取(storage.SetEngineOptionsNewEngine), 运行时修改引擎 KV 需重启服务(管理端 GET /admin/config/get_engine_hint 亦有提示)。

引擎选择

FCB_STORAGE_ENGINE=local    # 启动默认(KV storage_engine 为空时生效)
FCB_STORAGE_ENGINE=s3
FCB_STORAGE_ENGINE=webdav

非法值直接启动失败:FCB_STORAGE_ENGINE 无效值 "xxx",仅支持 local|s3|webdav

26.9 运行时热切换:管理端 POST /admin/storage/switch(或后台设置页「存储引擎」卡)可在不重启的情况下切换引擎—— 先构建新引擎并健康检查,通过才生效;失败 503 保持原引擎。当前引擎持久化在 settings KV storage_engine(空=回落启动值)。 各引擎参数(存储目录/服务地址/存储桶/密钥)同样在后台设置页运行时可改;保存后对应引擎实例缓存失效,下次切换/构建生效。

文件归属引擎(26.9

每条分享记录(file_codes.engine)与上传会话(upload_chunks.engine / presign_upload_sessions.engine) 在创建时戳记当时的引擎名。下载、分片合并、删除按归属引擎操作——切换引擎后,旧引擎里的文件仍可正常下载与删除 (空戳为历史数据,回落当前引擎)。

按日期目录存储

文件落盘路径:[storage_path/]share/data/YYYY/MM/DD/<uuid>/<文件名>(如 share/data/2026/09/04/…)。 按日嵌套目录自然排序、无日月歧义、避免单日海量文件挤在单目录;三种引擎一致适用;历史路径记录在 file_codes.file_path,不受路径规则调整影响。

配置键与环境变量

引擎相关配置键(DB settings KV)可由环境变量种子注入(优先级:默认 < 环境变量 < DB KV):

KV 键 环境变量 引擎 说明
local_storage_path FCB_LOCAL_STORAGE_PATH local 本地存储根目录(容器内默认 /app/data
storage_path FCB_STORAGE_PATH 全部 存储相对路径前缀(空 = share/data/…
s3_access_key_id FCB_S3_ACCESS_KEY_ID s3 访问密钥
s3_secret_access_key FCB_S3_SECRET_ACCESS_KEY s3 私有密钥
aws_session_token FCB_AWS_SESSION_TOKEN s3 可选临时会话令牌
s3_bucket_name FCB_S3_BUCKET_NAME s3 桶名
s3_endpoint_url FCB_S3_ENDPOINT_URL s3 S3 兼容端点(MinIO/R2 等;AWS 原生可空)
s3_region_name FCB_S3_REGION_NAME s3 区域(默认 auto
s3_addressing_style FCB_S3_ADDRESSING_STYLE s3 auto/path/virtual
webdav_url FCB_WEBDAV_URL webdav WebDAV 服务地址(如 http://webdav:5000
webdav_username FCB_WEBDAV_USERNAME webdav 用户名
webdav_password FCB_WEBDAV_PASSWORD webdav 密码
webdav_root_path FCB_WEBDAV_ROOT_PATH webdav 根目录(默认 filebox_storage,不存在自动逐级创建)

FCB_STORAGE_ENGINE 本身不落库(GET /admin/config/get 中的 file_storage 为 KV 记忆键, 进程实际引擎以 FCB_STORAGE_ENGINE_engine_hint.storage_backend 为准)。

各引擎要点

本地引擎(local

  • 原子写:临时文件 + fsync + rename,避免半写文件。
  • 路径安全:SanitizePath + 符号链接逃逸双重防穿越。
  • Range 下载基于 SectionReader;分片按索引有序合并 + SHA256 校验,合并后清理分片目录。

S3 引擎(s3

  • 原生 multipart 流式合并(失败自动 Abort),分片落临时文件保证精确 Content-Length 与可重放。
  • 预签名 GET/PUT 直链(预签名直传唯一 direct 模式引擎)。
  • SDK 内置 5xx 指数退避重试;when_required 校验模式兼容 MinIO/R2 与纯流式转发。

WebDAV 引擎(webdav,重点优化)

  • 连接复用:池化 Transport,连接复用(实测 25 次请求仅 1 条 TCP 连接)。
  • 认证Basic + DigestRFC 2617 qop=authMD5/SHA-256)自动协商,401 挑战驱动。
  • RangeRange 头透传 + 206 解析,支持分块/断点下载。
  • 重试5xx/429/408 指数退避(封顶 2s ± 20% 抖动,尊重 Retry-After)。
  • 流式:下载经 io.Pipe 流式转发不落盘;上下文取消挂到响应体读完之后,防止提前断连。
  • 目录:按需逐级 MKCOL + 目录缓存,避免重复建目录。
  • 超时:可配置(webdav_url 同级暂无独立超时键,引擎默认值内置)。

健康检查

三引擎均实现 HealthChecklocal 写探针、s3 ListObjectsV2、webdav PROPFIND(根目录不存在时自建)。 服务启动时预检失败仅告警不阻断;运行状态可经 GET /api/v1/healthdata.storage 查看当前引擎名。

预签名直传支持矩阵

引擎 PresignPutURL / PresignGetURL init 返回 mode
s3 direct
local / webdav ErrNotSupported proxy(走服务端代理上传)

引擎不支持的操作经统一映射返回 501:

{ "code": 501, "msg": "当前存储引擎不支持该操作" }

Docker Compose 冒烟编排

deploy/docker-compose.yml 提供可选 profile(详见 deploy/README.md):

docker compose --profile minio up -d --build    # MinIO(含 mc 自动建桶)+ FCB_STORAGE_ENGINE=s3
docker compose --profile webdav up -d --build   # dufs WebDAV 冒烟(admin/admin123+ FCB_STORAGE_ENGINE=webdav
docker compose --profile redis up -d --build    # Redis 缓存增强(非引擎)

存储哨兵错误 → HTTP 状态

哨兵错误 HTTP 文案
ErrNotFound 404 文件不存在
ErrInvalidPath 400 非法文件路径
ErrUnavailable 503 存储服务不可用,请稍后再试
ErrNotSupported 501 当前存储引擎不支持该操作
ErrRangeNotSatisfiable 416 请求范围超出文件大小
ErrHashMismatch 400 分片哈希校验失败,请重新上传

容量超限(storageLimit,经容量预留判定)返回 507存储空间已达到管理员设置的容量上限