后台任务队列 (Task Queue)
SayClaw Admin 内置后台任务队列,统一管理对单台或多台服务器的异步操作。所有后台任务均持久化于 admin_tasks 表,可追溯、可重试。
架构
HTTP 请求 / 业务操作
↓
enqueueTask()
↓
admin_tasks(MySQL)
↓
taskWorker goroutine(每3秒轮询)
↓
execOnServer()
├── server_id = 空 / LOCAL_SERVER_ID → 本机直接执行
└── server_id = 远程 → SSH 到目标服务器执行
多服务器路由
每台受管服务器在 servers 表中记录 SSH 凭据:
| 字段 | 说明 |
|---|---|
ssh_user | SSH 用户名(默认 root) |
ssh_port | SSH 端口(默认 22) |
ssh_key_path | 私钥路径(默认 /root/.ssh/id_ed25519_openclaw) |
提交任务时携带 server_id,Worker 自动路由:
server_id为空 或 等于LOCAL_SERVER_ID环境变量 → 本机执行- 否则 → 查
servers表 → SSH 远程执行
任务类型
restart_service
重启 systemd 服务。
{
"type": "restart_service",
"server_id": "srv-xialong-01",
"payload": { "service": "openclaw" }
}
若重启
sayclaw-admin-api自身,系统先标记任务为done,再延迟1秒执行重启,避免任务状态 stuck。
sync_telegram
从 DB 读取最新 Telegram 配置,写入目标实例的 openclaw.json,并自动排队 restart_service。
{
"type": "sync_telegram",
"server_id": "srv-xialong-01",
"payload": { "instance_id": "oc-xialong-main" }
}
health_check
对指定 OC 实例执行健康检查,更新 oc_instances.health_status 和 oc_health_logs。
{
"type": "health_check",
"server_id": "srv-xialong-01",
"payload": { "instance_id": "oc-xialong-main" }
}
docker_op
对指定容器执行 start / stop / restart。
{
"type": "docker_op",
"server_id": "srv-xialong-01",
"payload": { "container": "sayclaw-litellm", "op": "restart" }
}
shell
执行白名单内的 shell 命令(安全限制)。
当前白名单:
nginx -tnginx -s reloadsystemctl status openclawsystemctl status sayclaw
{
"type": "shell",
"server_id": "srv-xialong-01",
"payload": { "cmd": "nginx -s reload" }
}
任务状态
| 状态 | 说明 |
|---|---|
pending | 等待执行 |
running | 执行中 |
done | 成功完成 |
failed | 执行失败(可重试) |
崩溃恢复: 服务重启时,自动把所有
running状态任务恢复为pending,防止任务永久卡死。
REST API
查询任务列表
GET /api/v1/tasks
Authorization: Bearer <token>
返回最近50条任务,按 ID 倒序。
创建任务
POST /api/v1/tasks
Content-Type: application/json
{
"type": "restart_service",
"server_id": "srv-xialong-01",
"payload": { "service": "openclaw" }
}
返回:
{ "task_id": 6, "message": "queued", "server_id": "srv-xialong-01" }
查询单个任务
GET /api/v1/tasks/:id
重试失败任务
POST /api/v1/tasks/:id/retry
将 failed 状态重置为 pending,等待下次 Worker 轮询执行。
DB Schema
CREATE TABLE admin_tasks (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(50) NOT NULL,
server_id VARCHAR(100) NULL COMMENT '目标服务器ID,NULL=本机',
payload JSON NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'pending',
result TEXT NULL,
created_by VARCHAR(100) NULL,
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
started_at DATETIME(3) NULL,
done_at DATETIME(3) NULL,
retries INT NOT NULL DEFAULT 0,
INDEX idx_status (status),
INDEX idx_created (created_at)
);
环境变量
| 变量 | 说明 | 示例 |
|---|---|---|
LOCAL_SERVER_ID | 当前机器在 servers 表中的 ID | srv-xialong-01 |
当 server_id 等于 LOCAL_SERVER_ID 时,任务直接本机执行(不走 SSH),避免自我 SSH 失败。
扩展指引:新增受管服务器
- 在
servers表插入记录
INSERT INTO sayclaw_admin.servers (id, name, ip, region, ssh_user, ssh_port, ssh_key_path, status)
VALUES ('srv-new-01', '新服务器', '1.2.3.4', 'gcp-tokyo', 'root', 22, '/root/.ssh/id_ed25519_openclaw', 'active');
- 把 admin-api 的 SSH 公钥推到目标服务器
ssh-copy-id -i /root/.ssh/id_ed25519_openclaw.pub [email protected]
- 提交任务时带上
server_id即可,Worker 自动通过 SSH 执行
{
"type": "docker_op",
"server_id": "srv-new-01",
"payload": { "container": "openclaw-main", "op": "restart" }
}