zenowell.cc:9989,内网口 127.0.0.1:9990。
Authorization: Bearer rctk_xxxxxxxx?token= 或 Cookie —— 服务端会拒收 rctk_ 新密钥GET /api/state # 全量状态: active/queue/gpu/ram/resources/history
GET /api/queue # 排队列表
GET /api/resource?name=llm # 单个资源明细
GET /api/log?n=100 # 中控日志尾部
GET /api/history # 审计历史
GET /api/gpu-hist?window=3600&points=180 # GPU 温度曲线
GET /api/metrics # Prometheus 指标
GET /api/health # 健康探测(免鉴权)POST /api/action)POST /api/action
Content-Type: application/json
Authorization: Bearer rctk_xxxxxxxx
{"op": "request", "name": "llm", "minutes": 120, "note": "客户咨询"}
{"op": "job", "name": "llm", "minutes": 120, "job": "job-42"}
{"op": "heartbeat", "name": "llm", "job": "job-42"}
{"op": "release", "name": "llm", "note": "做完了"}
{"op": "cancel", "name": "llm"}
{"op": "adopt", "name": "video"}request — 申请租约。显存够立刻上线,不够排队,永不抢占job — 申请 + 立刻心跳,适合"我马上要用"的长任务heartbeat — 续租,防中台判定空闲后自动释放release — 释放正在运行的租约cancel — 取消排队中的请求,不动任何运行中的服务adopt — 纳管一个已经在外跑的进程(RCT 认领它)release 会真的
systemctl stop 停掉当时正在跑的同名服务。
import httpx, json
RCT = "http://zenowell.cc:9989"
KEY = "rctk_xxxxxxxx"
H = {"Authorization": f"Bearer {KEY}"}
def rct(op, name, **kw):
r = httpx.post(f"{RCT}/api/action", headers=H,
json={"op": op, "name": name, **kw}, timeout=30)
return r.json()
# 申请 → 拿到租约就干活, 拿不到就是排队(不阻塞等)
st = httpx.get(f"{RCT}/api/state", headers=H, timeout=10).json()
if st["active"] == "llm":
try:
run_my_job() # 你的活儿
rct("release", "llm", note="完成")
finally:
pass
elif any(q["name"] == "llm" for q in st.get("queue", [])):
print("排队中,前面还有活儿") # 不要 sleep 等!
else:
print(rct("request", "llm", minutes=120, note="客户咨询"))429。401 密钥无效 · 403 权限不足(程序密钥不能当管理员)·
404 资源不存在 · 409 操作冲突 · 429 限流 · 503 中控不可达
-np 1 的 1 是 1 个并发请求槽,
同一时刻 llm 槽只加载 1 个模型。
单请求上下文上限 = 262144 ÷ 1 = 131,072。
超过就直接报错(服务开了 --no-context-shift,不会自动丢历史),
提示和回复是合起来算的。
systemctl stop h3-video-server + pkill -9 去腾显存 ——
您正在跑的视频会被一次误点砸掉。现在全部改成排队, 绝不抢。