9.6 KiB
PRD ① 设备端(rk3588-agent + media-server)远程管理能力(V1)
1. 背景
当前 media-server 已提供 HTTP 控制台与配置热更新能力(/api/*、/api/config/reload、/api/config/rollback 等)。由于 大文件模型上传 在现有 C++ 自研 HTTP Server 上实现成本较高(需要流式接收/写盘/校验/限流),本期采用更工程化的拆分:
media-server:继续专注业务图(推理/推流/报警)与热更新。rk3588-agent(Go 新增常驻进程):对外提供局域网管理面能力:UDP 发现、模型/配置上传落盘、触发media-serverreload/rollback、代理读取 graphs/logs。
本 PRD 覆盖“轻量热更新/重载/回滚(业务图级)”。systemd/重启系统等运维级操作可作为后续扩展,但不作为 V1 验收项。
2. 目标
- 管理端可通过 UDP 广播在 1 秒内发现同网段 10 台设备(由
rk3588-agent响应)。 - 管理端可通过
rk3588-agent上传配置 JSON,设备端原子写入后触发media-serverreload 生效。 - 管理端可通过
rk3588-agent上传模型文件到设备固定目录,并返回可直接在配置中引用的model_path。 - 所有对外写操作必须鉴权(Token),读操作默认可不鉴权(可配置)。
3. 非目标(V1 不做)
- systemd start/stop/restart
media-server(可在 agent 后续扩展) - 设备重启/固件升级/插件升级
- 跨网段发现(保留后端可做网段扫描 fallback)
- 完整 RBAC/用户体系
4. 现状可复用能力(不修改语义)
- HTTP Server:
src/http_server.cpp - Graph/热更新:
GraphManager::ReloadFromFile、GraphManager::RollbackFromLastGood - 配置 Expand + Validate:
utils/config_expand.*、utils/config_schema.h - 运行状态:
GET /api/graphs、GET /api/graphs/{name}、GET /api/logs/recent
5. 新增功能范围(V1)
5.1 新增进程:rk3588-agent(Go)
rk3588-agent 作为常驻服务,提供:
- UDP 广播发现(Option A):对管理端 Search 做响应。
- HTTP 管理 API(对外):模型上传、配置下发、触发 reload/rollback、代理 graphs/logs。
- 本地调用
media-server:通过http://127.0.0.1:<media_port>/api/...触发 reload/rollback/读取 graphs/logs。
5.1.1 agent 代码目录结构(建议,开发可直接照此建工程)
建议以 Go module 形式独立工程(可放在同仓库 agent/ 目录,也可独立仓库)。
agent/
go.mod
cmd/
rk3588-agent/
main.go
internal/
config/ # 读取/校验 /etc/rk3588-agent/config.json
discovery/ # UDP 35688 discover responder
httpapi/ # 对外 HTTP 路由:/v1/* + auth
mediaserver/ # 对内 HTTP client:调用 127.0.0.1:9000/api/*
modelstore/ # 模型落盘/sha256/manifest
files/ # 原子写盘(tmp+rename)、权限校验
sysinfo/ # hostname/ip/uptime/device_id
log/ # 统一日志封装(stdout/journald)
5.2 media-server 变更范围(V1)
V1 目标是将大文件上传从 media-server 移出,因此 media-server 可不新增大文件上传接口。仅要求:
- 保持现有
/api/config/reload、/api/config/rollback、/api/graphs、/api/logs/recent等接口可用。 - (可选安全加固,非 V1 必须)限制
media-serverHTTP 仅监听127.0.0.1或对写接口增加 Token 鉴权。
6. 配置与落盘约定
6.1 新增 agent 配置项(建议)
agent 需要独立配置(例如 /etc/rk3588-agent/config.json)。建议:
{
"agent": {
"listen": "0.0.0.0:9100",
"token": "CHANGE_ME",
"require_token_for_read": false,
"discovery_enable": true,
"discovery_port": 35688,
"device_name": "rk3588-cam-01",
"device_id_path": "/var/lib/rk3588-agent/device_id",
"models_dir": "/opt/rk3588sys/models",
"max_upload_mb": 200,
"config_path": "/etc/rk3588sys/config.json",
"media_server_base_url": "http://127.0.0.1:9000",
"media_server_timeout_ms": 3000,
"media_server_retry": { "max_attempts": 3, "backoff_ms": [200, 500] }
}
}
字段说明(V1 关键字段):
config_path:agent 写入配置文件的目标路径(与 media-server--config一致)。device_id_path:device_id 持久化文件路径(不存在则自动生成并写入)。media_server_base_url:agent 调用 media-server 的本机地址,建议固定127.0.0.1。media_server_timeout_ms:agent 调用 media-server 的 HTTP 总超时。media_server_retry:仅对“控制类请求”(reload/rollback)启用的重试策略。
6.2 设备侧文件系统布局(部署约定)
为保证权限与可维护性,约定如下路径:
- 可执行文件:
/opt/rk3588sys/bin/media-server/opt/rk3588sys/agent/rk3588-agent
- 配置文件:
/etc/rk3588sys/config.json(media-server--config指向)/etc/rk3588-agent/config.json
- 状态/持久化:
/var/lib/rk3588-agent/device_id
- 模型仓库:
/opt/rk3588sys/models/manifest.json/opt/rk3588sys/models/files/*.rknn
说明:如不希望以 root 运行,可将
config_path改到/opt/rk3588sys/config/config.json并给 agent 用户写权限;V1 为减少权限复杂度,建议 agent 以 root 运行。
6.3 systemd service(部署字段,开发/运维可直接照抄)
6.3.1 rk3588-agent.service
路径建议:/etc/systemd/system/rk3588-agent.service
[Unit]
Description=RK3588Sys Agent
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
ExecStart=/opt/rk3588sys/agent/rk3588-agent --config /etc/rk3588-agent/config.json
Restart=always
RestartSec=2
WorkingDirectory=/
LimitNOFILE=65535
# 可选:基础加固(需要确认路径)
NoNewPrivileges=true
PrivateTmp=true
ProtectHome=true
ProtectSystem=full
ReadWritePaths=/etc/rk3588sys /etc/rk3588-agent /opt/rk3588sys/models /var/lib/rk3588-agent
[Install]
WantedBy=multi-user.target
6.3.2 media-server.service(建议统一纳入部署约定)
路径建议:/etc/systemd/system/media-server.service
[Unit]
Description=RK3588Sys Media Server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
ExecStart=/opt/rk3588sys/bin/media-server --config /etc/rk3588sys/config.json
Restart=always
RestartSec=2
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
V1 不要求 agent 控制 systemd,但要求两服务可开机自启。
6.4 模型目录结构
${models_dir}/manifest.json${models_dir}/files/<name>__<sha256>.<ext>(ext默认rknn,白名单控制)
7. 约束与安全
- agent 对外写接口必须
X-RK-Token。 - 上传限制:必须
Content-Length;大小不得超过max_upload_mb。 - agent 写盘采用原子写(临时文件 + rename)。
- agent 与
media-server的本地通信固定走127.0.0.1(避免暴露内部控制面)。
7.1 agent 内部调用 media-server 的 URL/超时/重试策略
agent 只调用 media-server 的既有接口(对内 base URL = media_server_base_url):
- Reload:
POST {base}/api/config/reload - Rollback:
POST {base}/api/config/rollback - Graphs:
GET {base}/api/graphs - Graph detail:
GET {base}/api/graphs/{name} - Logs:
GET {base}/api/logs/recent?limit=...
超时策略(建议默认值):
- 读接口(graphs/logs):总超时
1000ms(不重试) - 控制接口(reload/rollback):总超时
media_server_timeout_ms(默认3000ms),允许重试
重试策略(仅控制接口):
max_attempts = 3(首次 + 2 次重试)- 触发条件:连接失败/超时/5xx(不对 4xx 重试)
- backoff:
[200ms, 500ms]
配置下发联动策略(PUT /v1/config):
- agent 原子写入
config_path - 调用 reload(按控制接口重试策略)
- 若 reload 最终失败:调用 rollback(按控制接口重试策略)
- 返回 500,错误消息包含 reload 与 rollback 的结果(便于定位)
7.2 启动顺序与可用性
- 建议 systemd 启动顺序:两者都 After network-online。
- agent 对外可先起来;当 media-server 尚未启动时:
/v1/graphs、/v1/logs/recent返回 500(error=connect refused/timeout)/v1/config返回 500(写盘可成功,但 reload 失败会触发 rollback;错误信息提示 media-server 不可用)
8. 验收标准(Acceptance Criteria)
- 同网段 10 台设备,管理端 Search(UDP broadcast)在 1 秒内都能发现;列表包含
device_id/ip/agent_port/media_port/version/git_sha。 - agent
PUT /v1/config:- 发送合法 config,设备写盘并触发
media-serverreload 成功,graphs 状态正常。 - 发送非法 config,agent 返回 400;或 reload 失败则 agent 自动 rollback 并返回 500(错误信息可定位)。
- 发送合法 config,设备写盘并触发
- agent
PUT /v1/models/{name}:上传成功返回 sha256/path;在配置中引用该 path 并 reload 后,相关节点能正常 Init(以日志/metrics 验证)。 - 无 token 调用写接口返回 401;错误返回 JSON:
{"error":"..."}。
9. 开发任务拆分(建议)
- 新增
rk3588-agent:HTTP 服务 + Token 鉴权 + 日志 - UDP discovery:协议解析/回复、device_id 获取与持久化、停止逻辑
GET /v1/info:聚合 device/version/git_sha/ports/uptimePUT /v1/config:原子写盘 + 触发media-serverreload;失败自动 rollbackPUT /v1/models/{name}:流式落盘 + sha256 + manifest 写入GET /v1/models:读取 manifest- 代理接口:graphs、graph detail、logs recent、reload、rollback
- 统一错误码与日志(见接口清单表)