Files
storageNode/SUBSCRIPTION_GATEWAY.md
T

3.3 KiB
Raw Blame History

storageNode 内置订阅网关

8889 的 BackupSubServer 直接承载网关;无需独立进程或端口。空的 SubscriptionPrimaryUrl 保留旧快照模式;生产设 https://lionwebsite.xyz, SubscriptionEventDir 默认 /root/gallery/storageNode/subscription-events, 共享 SubscriptionSyncSecret,启用网关且无密钥会拒绝启动。

Nginx /sub/ 始终代理本机8889,并覆盖 X-Real-IP $remote_addr,保留原始 User-Agent/Range。只有 loopback 对端可以提供 X-Real-IP;公网直连8889 忽略所有代理来源 IP,X-Forwarded-For 始终不使用。

每个有效 v2/cat GET/HEAD 优先请求固定主站 origin,连接1秒、整次含完整正文3秒; 不传外部认证头、不跟随重定向,正文最大16MiB。网络错误、超时、5xx及3xx转备用快照; 400/403/404等其他状态透传,不使用旧缓存。GET/HEAD、Range和内容类型/范围头保留。 失败后熔断10秒,期间只读本地,到期只允许一个探测,成功后恢复逐请求访问主站。

每次请求建立UUID事件,字段为eventId/keyHash/client/clientIp/userAgent/occurredAt。 只存公开key的SHA256,不保存公开key、正文或密钥。UA保留合法Latin-1原始前缀,去除控制字符、非Latin-1替换为?,最大2048字符且UTF8<=2048bytes, 并在实际base64url事件头超过4096字符时继续截断;发主站UA与事件一致。 GET和HEAD均携带签名事件头;HEAD不会记日志。

签名请求头为 X-Subscription-Event(base64url无padding紧凑JSON)、 X-Subscription-Timestamp(epoch秒)、X-Subscription-Signature(HMAC-SHA256 hex)。 签名输入 v1\n<timestamp>\n<sha256(raw JSON bytes)>,UTF8。 主站已记但响应超时,也用原eventId回传,由主站receipt去重。

备用快照200/206 GET必须先写事件文件并fsync/原子rename/目录fsync才返回; 落盘失败或队列超限返回503,HEAD/404/416/503不写成功事件。 目录700,文件600。上限100000条/256MiB,保留16MiB磁盘余量;达到限制拒绝新成功更新, 不会静默丢弃旧记录。启动恢复所有json,元数据损坏会拒绝网关初始化,需先保留文件并排查。

后台单线程每10秒最多回传1批,100条且原始body<=256KiB,POST /internal/subscription-events,body {"events":[...]}。签名使用同一规则对原始body计算, 不含事件header。只清理本批 {"acknowledged":["<eventId>"]} 明确确认的事件, 并同步目录。网络/5xx/非法JSON/未确认/未知ID均保留原ID重试。上传不持有熔断器锁。 进程关闭会释放HTTP client和后台线程;Main shutdown hook管理完整服务生命周期。

/health/subscription 保持现有快照字段;/health/subscription-gateway 另报pendingCount/oldestAgeMillis/circuit/lastUploadAt/lastUploadState,无用户信息。

验证必须在部署手册指定的构建VM运行,不能在工作机执行Java编译/测试: mvn -B test。SubscriptionGatewayTest 使用真实本地HTTP主站和节点入口覆盖签名、 主站优先、fallback/持久化、ack/重启/同ID、HEAD、404、Range、timeout、熔断/单探测、 后台上传隔离、来源IP、路径编码、磁盘错误、批次字节上限、redirect和不完整/超大正文。 新增持久化协议全用Jackson树节点,不新增反射DTO。