Unleash 8.2.0 常用 CLI 命令与工具详解

Unleash 8.2.0 命令工具箱:官方无独立 CLI,以 REST API curl 实测为主线(登录会话、开关切换 on/off、策略灰度、Token 管理、SDK 消费端、审计查询)+ docker compose 运维命令,全部逐条真实回显。

UnleashUnleash2026/10/21

Unleash 8.2.0 常用 CLI 命令与工具详解

目标:给出 Unleash 8.2.0 日常管理与运维的命令工具箱。Unleash 官方不提供独立运维 CLI,日常操作工具由「REST API + curl(管理与自动化主线)」「Admin UI(人工操作)」「docker compose 运维命令(服务进程维护)」三部分组成,本文以 curl 实测为主体,所有请求与回显均在本机 Ubuntu 22.04 实测环境逐条真实执行并照抄。

一、环境信息

  • 操作系统:Ubuntu 22.04 LTS(x86_64),curl 7.81.0
  • Unleash:8.2.0(服务端口 4242,宿主侧映射 8144;部署过程见 《Unleash 8.2.0 Docker Compose 部署指南》)
  • 数据库:PostgreSQL 16(Compose 服务名 db)
  • 演示凭据(实验室口令,生产替换):管理账号 admin / q1w2e3r4;首启自动创建的 admin API Token *:*.q1w2e3r4
  • API 事实源:实例自带 OpenAPI 规范 http://localhost:8144/docs/openapi.json(规范标题 "Unleash API 8.2.0",162 个路径)

二、工具概览

工具定位适用场景
curl + REST API管理/自动化的命令行主线(本文主体)CI/CD 流水线建开关、脚本批量操作、健康巡检
Admin UI(Web 界面)人工管理入口日常人工建开关、看审计、配策略
docker compose 命令服务进程运维启停、日志、升级、备份
Unleash SDK(各语言)应用侧消费应用代码中评估开关、上报指标(非本文范围)

💡 说明:npm 生态中的 unleash-cli 是社区开发辅助包,并非官方运维 CLI,Unleash 8.x 官方仓库未提供任何命令行管理工具;这也是本文以 REST API 实测为主体的原因。端点行为以实例自带 OpenAPI 规范为最终事实源。

三、前置条件

3.1 确认服务健康

curl -s http://localhost:8144/health

实测回显:

{"health":"GOOD"}

3.2 准备认证凭据

Admin API 支持两种认证:API Token(推荐用于脚本)与登录会话 Cookie(模拟用户操作)。API Token 三类对照(实测归纳):

类型用途格式约束
adminAdmin API 全部操作必须以 *:*. 开头(全部项目+全部环境)
client服务端 SDK 拉取/上报必须绑定单一环境(不能 *,实测报错见 4.8 节)
frontend前端 SDK 评估绑定单一环境

本文示例统一使用 admin Token:

TOKEN='*:*.q1w2e3r4'
curl -s -H "Authorization: $TOKEN" http://localhost:8144/api/admin/projects | head -c 200

实测回显:

{"version":1,"projects":[{"name":"Default","id":"default","description":"Default project","health":100,"technicalDebt":0,"featureCount":0,...

⚠️ 注意:无凭据调用 Admin API 会返回 AuthenticationRequired 错误并指路登录端点(实测回显 "path":"/auth/simple/login")。

四、REST API 详解(curl 实测主线)

以下所有端点均实测于 Unleash 8.2.0。v8 相对旧文档变动较多(登录路径、开关切换端点、变体挂载点、全局列表端点都变了),凡遇 404 请先按 4.11 节方法核对 OpenAPI 规范。

4.1 健康与端点存活探测

# 主服务健康端点(官方监控探针用这个)
curl -s -o /dev/null -w '%{http_code} ' http://localhost:8144/health && curl -s http://localhost:8144/health

实测回显:

200 {"health":"GOOD"}
# 对照:Edge 健康端点 /internal-backstage/health 属于独立组件 Unleash Edge,
# 主服务上访问会回落到管理界面兜底页(返回 200 但内容是 SPA HTML)
curl -s http://localhost:8144/internal-backstage/health | head -4

实测回显(节选,证明是 SPA 兜底而非 JSON 健康):

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />

💡 说明:监控告警对接时只认 GET /health 的 {"health":"GOOD"};/internal-backstage/* 是 Unleash Edge(只读边缘组件)的端点族,主服务未部署 Edge 时一律是兜底页。

4.2 登录与会话管理

# 正确的登录端点是 /auth/simple/login
curl -si -X POST http://localhost:8144/auth/simple/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"q1w2e3r4"}' | head -6

实测回显:

HTTP/1.1 200 OK
RateLimit-Policy: 10;w=60
RateLimit-Limit: 10
RateLimit-Remaining: 9
RateLimit-Reset: 60
Content-Type: application/json; charset=utf-8
Set-Cookie: unleash-session=s%3A8rEA08nEDAxoJh8hji1zps2VoF5mT6Ry.%2BYokeySRGLaExIYMd1u01UxeJadZdv84JVuggg%2FV0G8; Path=/; Expires=Fri, 23 Oct 2026 11:17:47 GMT; HttpOnly; SameSite=Lax

带会话访问(Cookie jar 用法):

curl -s -c /tmp/unleash_cookies.txt -X POST http://localhost:8144/auth/simple/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"q1w2e3r4"}' > /dev/null
curl -s -b /tmp/unleash_cookies.txt http://localhost:8144/api/admin/ui-config | head -c 120

实测回显:

{"environment":"Open Source","flags":{"anonymiseEventLog":false,"enableLicense":false,...

⚠️ 排障实录:旧教程中的 POST /auth/login 在 8.2.0 是 404(实测回显 Cannot POST /auth/login),登录端点为 /auth/simple/login;登录限流 10 次/60 秒,脚本重试要控制频率。

4.3 项目 API

# 项目列表
curl -s -H "Authorization: $TOKEN" http://localhost:8144/api/admin/projects | python3 -c "import json,sys; d=json.load(sys.stdin); print([(p['id'],p['name'],p['featureCount']) for p in d['projects']])"

实测回显:

[('default', 'Default', 0)]

⚠️ 排障实录(v8 重要变化):8.2.0 的 Admin API 没有「创建项目」端点。实测 POST /api/admin/projects 返回:

{"name":"NotFoundError","message":"The path you were looking for (/api/admin/projects) is not available.",...}

同时实例 OpenAPI 规范中 /api/admin/projects 仅有 get。项目创建在 Admin UI 完成(首页「New project」);API 只覆盖项目查询、归档/恢复(POST /api/admin/projects/{id}/archive、/revive)、删除(POST /api/admin/projects/{id}/delete)等管理动作。

4.4 特性开关管理

# 创建开关(挂在 default 项目下)
curl -s -X POST http://localhost:8144/api/admin/projects/default/features \
  -H 'Content-Type: application/json' -H "Authorization: $TOKEN" \
  -d '{"name":"checkout-new-ui","description":"新版结算页灰度发布","type":"release"}'

实测回显:

{"name":"checkout-new-ui","description":"新版结算页灰度发布","type":"release","project":"default","stale":false,"createdAt":"2026-10-21T11:20:30.549Z","impressionData":false,"archived":false}
# 单个开关详情(含各环境启用状态)
curl -s -H "Authorization: $TOKEN" http://localhost:8144/api/admin/projects/default/features/checkout-new-ui \
  | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['name'], d['type'], [(e['name'],e['enabled']) for e in d['environments']])"

实测回显:

checkout-new-ui release [('development', True), ('production', True)]
# 开关检索列表(v8 用 search/features,旧 featureToggles 端点已移除)
curl -s -H "Authorization: $TOKEN" http://localhost:8144/api/admin/search/features | head -c 260

实测回显:

{"features":[{"type":"release","description":"新版结算页灰度发布","project":"default","favorite":false,"name":"checkout-new-ui","createdAt":"2026-10-21T11:20:30.549Z","stale":false,"archivedAt":null,"impressionData":false,...
# 标记开关为「过期」(stale)——v8 的 PATCH 是 RFC6902 数组形态,传对象会 400
curl -s -X PATCH http://localhost:8144/api/admin/projects/default/features/checkout-new-ui \
  -H 'Content-Type: application/json' -H "Authorization: $TOKEN" \
  -d '[{"op":"replace","path":"/stale","value":true}]' | head -c 150

实测回显:

{"name":"checkout-new-ui","description":"新版结算页灰度发布","type":"release","project":"default","stale":true,...

4.5 环境级开关切换

# 在 development 环境打开
curl -s -o /dev/null -w '%{http_code}\n' -X POST \
  http://localhost:8144/api/admin/projects/default/features/checkout-new-ui/environments/development/on \
  -H "Authorization: $TOKEN"

# 在 production 环境关闭
curl -s -o /dev/null -w '%{http_code}\n' -X POST \
  http://localhost:8144/api/admin/projects/default/features/checkout-new-ui/environments/production/off \
  -H "Authorization: $TOKEN"

实测回显(两次请求依次):

200
200

⚠️ 排障实录:旧版端点 POST /api/admin/projects/{id}/environments/{env}/toggles/{feature}/enabled 在 8.2.0 已移除,实测返回 404;v8 统一为 .../on 与 .../off(也可用 POST .../features/{featureName}/environments/{env}/off 批量端点 bulk_features)。

4.6 策略管理(灰度核心)

# 修改默认策略为 25% 渐进放量 + A/B 变体(PUT 全量更新;策略 ID 从开关详情或 playground 回显中获取,本例为 01M5F31YN6RKXZEQE08QFB26J6)
curl -s -o /dev/null -w '%{http_code}\n' -X PUT \
  http://localhost:8144/api/admin/projects/default/features/checkout-new-ui/environments/development/strategies/01M5F31YN6RKXZEQE08QFB26J6 \
  -H 'Content-Type: application/json' -H "Authorization: $TOKEN" \
  -d '{"name":"flexibleRollout","parameters":{"rollout":"25","groupId":"checkout-new-ui","stickiness":"default"},"constraints":[],"variants":[{"name":"variant-a","weight":500,"weightType":"variable","stickiness":"default","payload":{"type":"string","value":"A方案"}},{"name":"variant-b","weight":500,"weightType":"variable","stickiness":"default","payload":{"type":"string","value":"B方案"}}]}'

实测回显:

200
# 删除多余策略(本例中被删除的第二条 25% 策略 ID 为 01M5F33R8WK0JQKSEM2Y80CDJ9)
curl -s -o /dev/null -w '%{http_code}\n' -X DELETE \
  http://localhost:8144/api/admin/projects/default/features/checkout-new-ui/environments/development/strategies/01M5F33R8WK0JQKSEM2Y80CDJ9 \
  -H "Authorization: $TOKEN"

实测回显:

200
# 用官方 playground 端点核对评估过程(排障利器:逐条策略显示 rollout 与命中结果)
curl -s -X POST http://localhost:8144/api/admin/playground \
  -H 'Content-Type: application/json' -H "Authorization: $TOKEN" \
  -d '{"projects":["default"],"environment":"development","context":{"appName":"web-demo","userId":"7"}}' \
  | python3 -c "import json,sys; f=json.load(sys.stdin)['features'][0]; print('isEnabled:', f['isEnabled']); [print('rollout=', s['parameters'].get('rollout'), 'hit=', s['result']['enabled']) for s in f['strategies']['data']]"

实测回显:

isEnabled: False
rollout= 25 hit= False

⚠️ 排障实录:新建开关默认自带 rollout=100 的 default 策略,再新增 25% 策略与之是「或」关系,灰度不会生效(实测 12 个用户全量命中)。正确做法是修改默认策略本身;删除多余策略后 playground 逐条核对即可确认。

4.7 变体管理

⚠️ 排障实录:v8 已废弃环境级变体。实测对 PUT .../environments/development/variants 传变体数组返回:

{"name":"InvalidOperationError","message":"Environment variants deprecated for feature: checkout-new-ui. Use strategy variants instead.",...}

变体必须配置在策略上(4.6 节 PUT 请求体中的 variants 字段),评估时随策略命中返回,实测回显见 4.9 节 frontend API。

4.8 API Token 管理

# 创建 frontend 类型 Token(v8 字段名是 tokenName,不是 username)
curl -s -X POST http://localhost:8144/api/admin/api-tokens \
  -H 'Content-Type: application/json' -H "Authorization: $TOKEN" \
  -d '{"type":"frontend","project":"default","environment":"development","tokenName":"frontend-demo"}'

实测回显:

{"environment":"development","tokenName":"frontend-demo","projects":["*"],"secret":"*:development.47e03851864d27c0a2173469068f1901b03f8d71e5612217be4b7315","type":"frontend","alias":null,"project":"*","createdAt":"2026-10-21T11:21:00.948Z","secure":false}
# Token 列表
curl -s -H "Authorization: $TOKEN" http://localhost:8144/api/admin/api-tokens | head -c 220

实测回显:

{"tokens":[{"secret":"*:*.q1w2e3r4","tokenName":"admin","type":"admin","project":"*","projects":["*"],"environment":"*","expiresAt":null,...

⚠️ 排障实录(两条实测校验规则):

  1. 请求体用 username 会报 BadDataError: The /body/tokenName property is required——v8 字段名为 tokenName;
  2. client Token 传 "environment":"*" 报 BadDataError: Client token cannot be scoped to all environments——client 类型必须绑定单一环境。

4.9 SDK 消费端 API(开关生效验证)

# Frontend API:按用户上下文评估(前端 SDK 同款端点)
FTOKEN='*:development.47e03851864d27c0a2173469068f1901b03f8d71e5612217be4b7315'
curl -s -H "Authorization: $FTOKEN" 'http://localhost:8144/api/frontend?appName=web-demo&userId=2'

实测回显(灰中用户:enabled + 变体 payload):

{"toggles":[{"name":"checkout-new-ui","enabled":true,"variant":{"name":"variant-a","enabled":true,"payload":{"type":"string","value":"A方案"},"feature_enabled":true,"featureEnabled":true},"impressio
# Client API:服务端 SDK 拉取开关快照
CTOKEN='*:development.9fb2e61830948da3eda461f606779cc13a37293288ad075e5b6c7e3d'
curl -s -H "Authorization: $CTOKEN" http://localhost:8144/api/client/features | head -c 400

实测回显(节选):

{"version":2,"features":[{"name":"checkout-new-ui","type":"release","enabled":true,"project":"default","stale":false,"strategies":[{"name":"flexibleRollout","constraints":[],"parameters":{"groupId":"checkout-new-ui","rollout":"25","stickiness":"default"},"variants":[...
# SDK 注册与指标上报(v8 要求 bucket.toggles 为对象,数组会 400)
curl -s -X POST http://localhost:8144/api/client/register \
  -H 'Content-Type: application/json' -H "Authorization: $CTOKEN" \
  -d '{"appName":"web-demo","instanceId":"inst-1","sdkVersion":"unleash-client-node:6.0.0","connectVia":"streaming","interval":10000,"started":"2026-10-21T11:30:00Z","strategies":["default"]}' \
  -w '\nHTTP %{http_code}\n'

实测回显:

HTTP 202

💡 说明:Frontend API 与 Client API 的响应存在服务端缓存(秒级),改完策略立即评估可能拿到旧结果——实测排障时先用 playground 端点核对最新评估,再等缓存刷新验证端到端。

4.10 审计与实例运维查询

# 审计事件流(谁在何时改了什么,含变更前后数据)
curl -s -H "Authorization: $TOKEN" 'http://localhost:8144/api/admin/events?limit=2' | head -c 300

实测回显(节选):

{"version":1,"events":[{"id":17,"type":"feature-strategy-remove","createdBy":"admin","createdAt":"2026-10-21T11:23:04.388Z","createdByUserId":-42,"data":null,"preData":{"id":"01M5F33R8WK0JQKSEM2Y80CDJ9","name":"flexibleRollout",...
# 实例统计
curl -s -H "Authorization: $TOKEN" http://localhost:8144/api/admin/instance-admin/statistics \
  | python3 -c "import json,sys; d=json.load(sys.stdin); print({k:d[k] for k in ['projects','users','environments'] if k in d}, d.get('apiTokens'))"

实测回显:

{'projects': 1, 'users': 1, 'environments': 2} {'client': 1, 'admin': 1, 'frontend': 1}
# 环境列表(含各环境开关计数)
curl -s -H "Authorization: $TOKEN" http://localhost:8144/api/admin/environments | head -c 300

实测回显:

{"version":1,"environments":[{"name":"development","type":"development","sortOrder":2,"enabled":true,"protected":false,"requiredApprovals":null,"projectCount":1,"apiTokenCount":2,"enabledToggleCount":1},{...

4.11 OpenAPI 规范自查(遇 404 的标准动作)

实例自带完整规范,404 时先查规范再猜路径:

curl -s http://localhost:8144/docs/openapi.json | python3 -c "
import json,sys
spec=json.load(sys.stdin)
print(spec['info']['title'], spec['info']['version'], '| paths:', len(spec['paths']))
for p,ops in sorted(spec['paths'].items()):
    if 'features' in p and 'environments' in p and 'on' in str(ops):
        print(' ', sorted(ops.keys()), p)" | head -8

实测回显:

Unleash API 8.2.0 | paths: 162
  ['get'] /api/admin/projects/{projectId}/features/{featureName}/environments/{environment}
  ['post'] /api/admin/projects/{projectId}/features/{featureName}/environments/{environment}/off
  ['post'] /api/admin/projects/{projectId}/features/{featureName}/environments/{environment}/on
  ['get', 'post'] /api/admin/projects/{projectId}/features/{featureName}/environments/{environment}/strategies
  ['get', 'patch', 'put'] /api/admin/projects/{projectId}/features/{featureName}/environments/{environment}/variants

交互式页面在 http://<实例>:8144/docs/openapi/(浏览器打开可在线试调)。

五、docker compose 运维命令

服务进程的日常维护在部署目录 /opt/unleash/ 下执行(部署与升级全流程见 《Unleash 8.2.0 Docker Compose 部署指南》):

cd /opt/unleash

# 状态总览(两个服务均 healthy 才算正常)
docker compose ps

# 实时日志(主服务)
docker compose logs -f web

# 重启主服务(改环境变量无效,必须 up -d 重建)
docker compose restart web

# 修改编排后应用变更
docker compose up -d

# 停止 / 恢复
docker compose stop
docker compose start

# 数据库逻辑备份
docker compose exec db sh -c 'pg_dump -U unleash_user unleash' > /opt/unleash/backup/unleash_$(date +%F).sql

# 升级版本:改 image tag 后拉取并重建
docker compose pull web && docker compose up -d web

docker compose ps 实测回显(正常态):

NAME               IMAGE                           STATUS                    PORTS
unleash-8.2.0-db   postgres:16                     Up 2 minutes (healthy)    5432/tcp
unleash-8.2.0-web  unleashorg/unleash-server:8.2.0 Up 6 seconds (healthy)    0.0.0.0:8144->4242/tcp, [::]:8144->4242/tcp

docker compose exec db sh -c 'pg_dump -U unleash_user unleash | head -8' 实测回显:

--
-- PostgreSQL database dump
--

\restrict MZvhQgQahsx8a5jYk43NMWTRGCQlZGgFPZrCTWrMqvvgtFvXfILcsRZbE56lwk3

-- Dumped from database version 16.15 (Debian 16.15-1.pgdg13+2)
-- Dumped by pg_dump version 16.15 (Debian 16.15-1.pgdg13+2)

六、注意事项

  • 凭据分级:脚本用 admin Token 时遵守最小化原则——能用 client/frontend Token 的场景不要用 admin Token;Token 按项目+环境收敛影响面(4.8 节两条校验规则)。
  • 限流意识:登录 10 次/60 秒;SDK 注册/上报默认 6000 次/分钟(超限 429),高频脚本先核对配置参数详解篇的限流变量。
  • 缓存延迟:策略变更后 Frontend/Client API 有秒级缓存,验证生效顺序=playground → frontend API。
  • v8 端点变动:/auth/login、toggles/.../enabled、/api/admin/featureToggles 均已移除,替换为 /auth/simple/login、.../on|off、/api/admin/search/features;变体只挂在策略上;PATCH 开关用 RFC6902 数组形态。
  • 审计兜底:所有 API 变更都会写入审计事件(/api/admin/events),排障与合规回溯优先看这里。

七、常见问题

Q1:脚本调 Admin API 全部 401? 未带 Authorization 头或 Token 失效;无凭据时的标准回显是 AuthenticationRequired JSON(内含正确登录路径提示),先修认证再查别的。

Q2:POST /api/admin/projects 404? 8.2.0 无创建项目端点(见 4.3 节实录),项目在 Admin UI 创建;API 只做查询与归档/恢复/删除。

Q3:改了策略但评估结果不变? 三步排查:① 是否存在默认 rollout=100 策略与新增策略「或」并存(4.6 节实录);② 用 playground 核对最新评估;③ Frontend/Client API 秒级缓存未刷新。

Q4:创建 Token 报 tokenName required? v8 字段名是 tokenName;client 类型还不能传 "environment":"*"(4.8 节实录)。

Q5:PUT variants 报 deprecated? 变体已迁移到策略维度(4.7 节实录),挂在策略请求体的 variants 字段上。

Q6:PATCH 开关报 must be array? PATCH 是 RFC6902 数组形态:[{"op":"replace","path":"/stale","value":true}](4.4 节实录)。

八、参考链接