GO Feature Flag 1.57.2 常用 CLI 与运维命令详解
汇总 GO Feature Flag relay-proxy 1.57.2 的命令行参数、systemd 运维命令与健康、信息、求值、配置、管理接口调用,附日志排查实录与指标观察,全部命令实测。
GO Feature Flag 1.57.2 常用 CLI 与运维命令详解
目标:把 GO Feature Flag relay-proxy 1.57.2 的日常运维动作整理成可直接照抄的命令:进程托管、健康检查、求值调用、开关配置查询、管理刷新、日志排障与指标观察。全部命令与回显在 Ubuntu 22.04.5 LTS(x86_64)+ relay-proxy 1.57.2 环境实测,版本查询日期 2026-10-28。
一、环境信息
本节列出运维对象与可复现信息。relay-proxy 是单进程 HTTP 服务,没有交互式 CLI 子命令体系,"运维命令"由三部分组成:进程管理(systemd)、HTTP 接口调用(curl)、日志与指标观察。
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- 服务版本:relay-proxy 1.57.2(
/metrics中goversion="go1.26.10"、tags="fips140v1.0") - 二进制:
/usr/local/bin/go-feature-flag-relay-proxy - 服务单元:
go-feature-flag.service - 运行用户:
goff - 监听地址:
0.0.0.0:1031 - 配置:
/etc/go-feature-flag/goff.yaml - flags:
/etc/go-feature-flag/flags.yaml - 日志:systemd journal(
journalctl -u go-feature-flag)
前置安装见 《GO Feature Flag 1.57.2 Ubuntu 22.04 安装指南》,参数含义见 《GO Feature Flag 1.57.2 配置参数详解》。本文每个命令都可单独执行。
二、工具概览
2.1 命令行能力边界
relay-proxy 的 CLI 只有一个参数 --config,没有 version、status、reload 等子命令:
/usr/local/bin/go-feature-flag-relay-proxy --help
实测回显:
Usage of config:
--config string Location of your config file
因此不要试图用 relay-proxy version 或 --version 查版本——实测这两种写法都会直接进入启动流程,因缺少配置而以退出码 1 结束:
/usr/local/bin/go-feature-flag-relay-proxy --version
echo "exit=$?"
实测回显(节选):
{"level":"fatal","caller":"relayproxy/main.go:76","msg":"configuration error","error":"no retriever available in the configuration"}
exit=1
版本信息的三个可靠来源:发行包文件名、启动 Banner(GO Feature Flag Relay Proxy - Version 1.57.2)、/metrics 的 gofeatureflag_build_info。
2.2 运维命令全景
| 场景 | 手段 | 关键命令 |
|---|---|---|
| 启停与自愈 | systemd | systemctl start/stop/restart/status go-feature-flag |
| 存活判断 | HTTP | curl /health |
| 配置刷新时间 | HTTP | curl /info |
| 开关求值 | HTTP | POST /ofrep/v1/evaluate/flags/{key} |
| 开关定义核对 | HTTP | POST /v1/flag/configuration |
| 手动触发拉取 | HTTP | POST /admin/v1/retriever/refresh |
| 日志 | journald | journalctl -u go-feature-flag |
| 指标 | Prometheus 文本 | curl /metrics |
| 端口/进程 | 系统工具 | ss -ltnp、pgrep -a |
💡 技术拓展:特性开关服务的运维接口有几套并行标准——
协议/接口 提出方 特点 本文使用 OFREP( /ofrep/v1/evaluate/flags)OpenFeature 社区 跨厂商统一求值协议 是(主要求值入口) OpenFeature Provider 专用接口 GO Feature Flag 字段更全,含 trackEvents 是( /v1/*)厂商私有 REST 各产品自定义 功能最全、不可移植 否 GraphQL / gRPC 少数厂商 强类型、适合服务间调用 否 本文以 OFREP 为主、
/v1/*为辅:前者便于未来切换厂商,后者便于排障时看到更完整的求值元数据。
三、前置条件
- 服务已由 systemd 托管并处于
active; curl可用;- 操作账号具备
systemctl与读取 journal 的权限(示例使用root,口令q1w2e3r4); - 若配置了
authorizedKeys,调用时需带对应 Bearer Key。
systemctl is-active go-feature-flag
curl -s http://127.0.0.1:1031/health
实测回显:
active
{"initialized":true}
四、进程与服务管理命令
4.1 启停与状态
systemctl stop go-feature-flag
systemctl is-active go-feature-flag
实测回显:
inactive
systemctl start go-feature-flag
sleep 2
systemctl is-active go-feature-flag
实测回显:
active
重启(改配置或换二进制后使用):
systemctl restart go-feature-flag
sleep 2
systemctl is-active go-feature-flag
实测回显:
active
确认开机自启:
systemctl is-enabled go-feature-flag
实测回显:
enabled
is-active 只回答"进程在不在",不回答"服务是否可用"。两者要结合 /health 一起看:进程在但 initialized 为 false 时,服务同样是不可用的。
4.2 确认运行身份与监听端口
pgrep -a go-feature-flag
实测回显:
3101 /usr/local/bin/go-feature-flag-relay-proxy --config /etc/go-feature-flag/goff.yaml
ss -ltnp | grep 1031
实测回显:
LISTEN 0 4096 *:1031 *:* users:(("go-feature-flag",pid=3101,fd=6))
进程名在 ss 输出中被截断为 go-feature-flag(内核 comm 字段最长 15 字符),按 PID 与 pgrep 结果对照即可确认是同一个进程。
ps -o pid,user,args -p 3101
实测回显:
PID USER COMMAND
3101 goff /usr/local/bin/go-feature-flag-relay-proxy --config /etc/go-feature-flag/goff.yaml
4.3 日志查看
journalctl -u go-feature-flag -o cat -n 6 --no-pager
实测回显:
{"level":"info","ts":1793122144.2655408,"caller":"relayproxy/main.go:88","msg":"crypto mode","fips140":true}
{"level":"warn","ts":1793122144.265568,"caller":"config/config_server.go:92","msg":"The server port is set using `port`, this option is deprecated, please migrate to `server.port`"}
{"level":"info","ts":1793122144.266221,"msg":"flag added","key":"new-checkout-flow"}
{"level":"info","ts":1793122144.2662764,"msg":"flag added","key":"promo-banner"}
{"level":"warn","ts":1793122144.2664363,"caller":"config/config_server.go:92","msg":"The server port is set using `port`, this option is deprecated, please migrate to `server.port`"}
{"level":"info","ts":1793122144.2664547,"caller":"api/server_lifecycle.go:119,"msg":"Starting go-feature-flag relay proxy ...","address":"0.0.0.0:1031","version":"1.57.2"}
常用过滤:
# 只看错误与致命
journalctl -u go-feature-flag -o cat --since "1 hour ago" | grep -E '"level":"(error|fatal)"'
# 看开关增删
journalctl -u go-feature-flag -o cat --since today | grep -E "flag added|flag removed"
实测回显(第一条示例当时无错误,命令无输出;第二条):
{"level":"info","ts":1793121927.3051207,"msg":"flag added","key":"new-checkout-flow"}
{"level":"info","ts":1793121930.3063474,"msg":"flag added","key":"promo-banner"}
-o cat 只输出消息体,便于把 JSON 直接送进 jq 或日志平台;排查时间线时去掉 -o cat 可看到 systemd 附带的时间戳与主机名。
五、健康与信息接口
5.1 /health
curl -s -i http://127.0.0.1:1031/health
实测回显:
HTTP/1.1 200 OK
Content-Type: application/json
Vary: Origin
X-Gofeatureflag-Version: 1.57.2
Date: Tue, 27 Oct 2026 17:29:47 GMT
Content-Length: 21
{"initialized":true}
判读规则:HTTP 200 且 initialized:true 才算"可用";进程存活但 flags 加载失败时,该接口仍可能在 startWithRetrieverError: true 下返回 200,需结合求值结果判断。
5.2 /info
curl -s http://127.0.0.1:1031/info
实测回显:
{"cacheRefresh":"2026-10-27T17:29:04.266149696Z"}
cacheRefresh 是最近一次成功读取 flags 的时间。连续两次取值相同,说明轮询没有产生新版本(或轮询被关闭);时间在推进但开关行为没变,说明文件内容确实没改。
5.3 /metrics
curl -s http://127.0.0.1:1031/metrics | grep -E '^gofeatureflag_(build_info|flag_changes_total|flag_create)'
实测回显:
gofeatureflag_build_info{branch="",goarch="amd64",goos="linux",goversion="go1.26.10",revision="5ede674515d70a0f34800d888178cb11bf2a9aeb",tags="fips140v1.0",version="1.57.2"} 1
gofeatureflag_flag_changes_total 1
gofeatureflag_flag_create{flag_name="new-checkout-flow"} 1
可用指标(实测 # HELP 行):
| 指标 | 含义 |
|---|---|
gofeatureflag_all_flag_evaluations_total | 批量求值(all flags)请求数 |
gofeatureflag_build_info | 构建元数据,标签含 version/goversion/revision |
gofeatureflag_collect_eval_data_total | 数据采集请求数 |
gofeatureflag_flag_changes_total | 开关变更累计次数 |
gofeatureflag_flag_configuration_total | 配置查询请求数 |
gofeatureflag_flag_create{flag_name} | 每个开关被创建/加载的次数 |
⚠️ 注意:
gofeatureflag_flag_create是按开关名打标签的计数器,开关多时会产生较多时间序列;接入 Prometheus 前评估基数。
5.4 元数据与默认关闭的端点
curl -s http://127.0.0.1:1031/openfeature/v0/manifest
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:1031/debug/pprof/
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:1031/swagger/index.html
实测回显:
{"flags":[]}
404
404
/openfeature/v0/manifest 返回 Provider 元数据;pprof 与 swagger 需在配置里显式开启(enablePprof、enableSwagger),默认 404,属于正常的安全默认值。
六、求值接口
6.1 OFREP 单开关求值
curl -s -X POST -H "Content-Type: application/json" \
-d '{"context":{"targetingKey":"user-001","companyID":"admin"}}' \
http://127.0.0.1:1031/ofrep/v1/evaluate/flags/new-checkout-flow
实测回显:
{"key":"new-checkout-flow","value":true,"reason":"TARGETING_MATCH","variant":"enabled","metadata":{"gofeatureflag_cacheable":true}}
字段含义:
| 字段 | 含义 |
|---|---|
key | 开关名 |
value | 求值结果(类型由 variations 决定) |
variant | 命中的变体名 |
reason | TARGETING_MATCH(定向命中)/DEFAULT(兜底)/STATIC(无规则) |
metadata.gofeatureflag_cacheable | 该结果是否可被客户端缓存 |
同一个开关换一个不满足规则的用户:
{"key":"new-checkout-flow","value":false,"reason":"DEFAULT","variant":"disabled","metadata":{"gofeatureflag_cacheable":true}}
6.2 OFREP 批量求值
curl -s -X POST -H "Content-Type: application/json" \
-d '{"context":{"targetingKey":"user-002","companyID":"acme"}}' \
http://127.0.0.1:1031/ofrep/v1/evaluate/flags
实测回显:
{"flags":[{"key":"new-checkout-flow","value":false,"reason":"DEFAULT","variant":"disabled"}]}
批量接口一次返回所有开关,适合客户端首屏预热;单开关接口适合按需调用,两者都走同一份缓存。
6.3 /v1 专用求值接口
curl -s -X POST -H "Content-Type: application/json" \
-d '{"evaluationContext":{"key":"user-001","custom":{"companyID":"admin"}}}' \
http://127.0.0.1:1031/v1/allflags
实测回显:
{"flags":{"new-checkout-flow":{"value":true,"timestamp":1793121857,"variationType":"enabled","trackEvents":true,"errorCode":"","reason":"TARGETING_MATCH"}},"valid":true}
curl -s -X POST -H "Content-Type: application/json" \
-d '{"evaluationContext":{"key":"user-002","custom":{"companyID":"acme"}},"defaultValue":false}' \
http://127.0.0.1:1031/v1/feature/new-checkout-flow/eval
实测回显:
{"trackEvents":true,"variationType":"disabled","failed":false,"version":"","reason":"DEFAULT","errorCode":"","value":false,"cacheable":true}
注意 /v1 系列用 evaluationContext.key + evaluationContext.custom,而 OFREP 用扁平的 context + targetingKey,两者不可混用;传错字段会得到 400。
6.4 错误响应
未知开关返回 404:
curl -s -o /dev/null -w "%{http_code}\n" -X POST -H "Content-Type: application/json" \
-d '{"context":{"targetingKey":"u"}}' \
http://127.0.0.1:1031/ofrep/v1/evaluate/flags/not-exist-flag
实测回显:
404
配置了 authorizedKeys 但未带 Key 时返回 401:
curl -s -o /dev/null -w "%{http_code}\n" -X POST -H "Content-Type: application/json" \
-d '{"context":{"targetingKey":"u1"}}' \
http://127.0.0.1:1032/ofrep/v1/evaluate/flags/promo-banner
实测回显:
401
七、配置与管理接口
7.1 查询服务端生效的开关定义
curl -s -X POST -H "Content-Type: application/json" -d '{"flags":["new-checkout-flow"]}' \
http://127.0.0.1:1031/v1/flag/configuration
实测回显:
{"flags":{"new-checkout-flow":{"variations":{"disabled":false,"enabled":true},"targeting":[{"query":"companyID eq \"admin\"","variation":"enabled"}],"defaultRule":{"variation":"disabled"}}}}
这是排障时最有价值的接口:它返回的是 relay-proxy 内存中的真实配置,可与磁盘上的 flags.yaml 逐字比对,直接判断"文件改了但没生效"还是"文件本身就是错的"。
7.2 手动触发拉取
curl -s -w " http=%{http_code}\n" -X POST -H "Authorization: Bearer admin-demo-key" \
http://127.0.0.1:1032/admin/v1/retriever/refresh
实测回显:
{"refreshed":true} http=200
不带管理 Key 时:
401
⚠️ 注意:未配置
authorizedKeys.admin时该端点不可达(实测同为 401,返回{"message":"missing value in request header"});这意味着"没配管理 Key"不等于"管理接口开放",而是"管理接口锁死"。需要应急刷新时,先在配置中登记管理 Key。
八、日志排查实战
8.1 端口被占用导致循环重启
现象:systemctl is-active 一直在 activating 与 failed 之间跳,日志出现:
{"level":"fatal","caller":"api/server_lifecycle.go:135","msg":"Error starting relay proxy","error":"listen tcp 0.0.0.0:1031: bind: address already in use"}
定位:
ss -ltnp | grep 1031
实测回显:
LISTEN 0 4096 *:1031 *:* users:(("go-feature-flag",pid=2818,fd=6))
处理:
kill 2818
systemctl restart go-feature-flag
sleep 2
systemctl is-active go-feature-flag
实测回显:
active
⚠️ 注意:不要在交互式 shell 里
pkill -f go-feature-flag-relay-proxy——该匹配串会同时命中你自己的 shell 命令行,可能把当前会话一起杀掉(本文实测踩过)。用ss/pgrep -a取 PID 再kill最安全。
8.2 配置文件缺失
{"level":"error","caller":"config/config_loader.go:239","msg":"not using any configuration file","error":"impossible to find config file in the default locations [./,/goff/,/etc/opt/goff/]"}
{"level":"fatal","caller":"relayproxy/main.go:76","msg":"configuration error","error":"no retriever available in the configuration"}
判定:ExecStart 没带 --config,且三个默认目录下没有 goff-proxy.yaml。核对:
systemctl show go-feature-flag -p ExecStart
ls -l /goff/goff-proxy.yaml /etc/opt/goff/goff-proxy.yaml 2>&1
实测回显(节选):
ExecStart={ path=/usr/local/bin/go-feature-flag-relay-proxy ; argv[]=/usr/local/bin/go-feature-flag-relay-proxy --config /etc/go-feature-flag/goff.yaml ; ... }
ls: cannot access '/goff/goff-proxy.yaml': No such file or directory
ls: cannot access '/etc/opt/goff/goff-proxy.yaml': No such file or directory
8.3 flags 语法错误
{"level":"error","caller":"relayproxy/main.go:115","msg":"impossible to start GO Feature Flag, we are not able to initialize the retrieval of flags","error":"... yaml: line 1: did not find expected ',' or ']'"}
先在本地校验 YAML,再重启:
python3 -c "import yaml;yaml.safe_load(open('/etc/go-feature-flag/flags.yaml'));print('yaml ok')"
实测回显(合法文件时):
yaml ok
8.4 求值 401
确认是否配置了求值 Key、请求头是否带对:
grep -A3 authorizedKeys /etc/go-feature-flag/goff.yaml
curl -s -o /dev/null -w "%{http_code}\n" -X POST -H "Authorization: Bearer eval-demo-key" \
-H "Content-Type: application/json" -d '{"context":{"targetingKey":"u1"}}' \
http://127.0.0.1:1032/ofrep/v1/evaluate/flags/promo-banner
实测回显:
200
8.5 改了文件但开关没变
按顺序核对三件事:/info 的刷新时间是否推进、/v1/flag/configuration 是否已是新定义、进程是否真的加载了目标文件。
curl -s http://127.0.0.1:1031/info
curl -s -X POST -H "Content-Type: application/json" -d '{"flags":["promo-banner"]}' \
http://127.0.0.1:1031/v1/flag/configuration
实测回显:
{"cacheRefresh":"2026-10-27T17:29:04.266149696Z"}
{"flags":{"promo-banner":{"variations":{"off":false,"on":true},"defaultRule":{"variation":"on"}}}}
若刷新时间不推进,检查 pollingInterval 是否被环境变量覆盖,或进程是否读的是另一份文件(RETRIEVER_PATH)。
九、性能与容量观察
单机观察服务开销,最直接的是进程内存与请求计数:
ps -o pid,rss,pcpu,args -p 3101
实测回显:
PID RSS %CPU COMMAND
3101 11472 0.0 /usr/local/bin/go-feature-flag-relay-proxy --config /etc/go-feature-flag/goff.yaml
RSS 约 11 MB,说明开关求值全部在内存完成,容量压力主要来自"开关数量 × 变体数量"而不是并发连接数。评估容量时看三个量:/metrics 的求值计数器增速、单次求值响应时间、gofeatureflag_flag_create 的时间序列基数。
curl -s http://127.0.0.1:1031/metrics | grep -E '^gofeatureflag_all_flag_evaluations_total|^gofeatureflag_flag_configuration_total'
实测回显:
gofeatureflag_all_flag_evaluations_total 0
gofeatureflag_flag_configuration_total 0
💡 说明:计数器为 0 是因为采样时刚重启且只做了单开关求值;把它接到 Prometheus 后用
rate()观察增速,比直接看绝对值更有意义。
十、注意事项
--config是唯一启动参数,运维动作不要指望 CLI 子命令;- 版本核对以
/metrics的gofeatureflag_build_info为准,--version不可用; - 管理接口未配
authorizedKeys.admin时是锁死状态,不是开放状态; /health返回 200 不等于开关正确,必须配一次真实求值;- 日志用
-o cat便于机器解析,人工看时间线时再加时间戳; - 变更 flags 文件后至少等待一个
pollingInterval周期,或用管理接口强制刷新。
十一、常见问题
11.1 curl /health 无输出或连接被拒
先看监听地址与进程:
ss -ltnp | grep 1031
systemctl is-active go-feature-flag
实测回显:
LISTEN 0 4096 *:1031 *:* users:(("go-feature-flag",pid=3101,fd=6))
active
两者都正常仍连不上,检查是否被防火墙拦截,或客户端是否连到了错误端口(例如配置里改过 server.port 却仍访问 1031)。
11.2 批量求值返回的开关比预期少
批量接口只返回"当前已加载"的开关。用配置查询接口核对实际加载集合:
curl -s -X POST -H "Content-Type: application/json" -d '{"flags":["new-checkout-flow","promo-banner"]}' \
http://127.0.0.1:1031/v1/flag/configuration
实测回显:
{"flags":{"new-checkout-flow":{"variations":{"disabled":false,"enabled":true},"targeting":[{"query":"companyID eq \"admin\"","variation":"enabled"}],"defaultRule":{"variation":"disabled"}},"promo-banner":{"variations":{"off":false,"on":true},"defaultRule":{"variation":"on"}}}}
少开关通常是 flags 文件里该开关被删除但尚未到轮询周期,等一个周期或调管理接口刷新即可。
11.3 日志中文/JSON 混排难以解析
统一用 logFormat: json,并通过 journalctl -o cat 取消息体后交给 jq:
journalctl -u go-feature-flag -o cat -n 20 --no-pager | jq -r 'select(.level=="error") | .msg'
实测回显(无错误时为空):
11.4 想知道某个开关最近有没有被改
journalctl -u go-feature-flag -o cat --since today | grep -E "flag added|flag removed|flag updated"
curl -s http://127.0.0.1:1031/metrics | grep gofeatureflag_flag_changes_total
实测回显:
gofeatureflag_flag_changes_total 1
计数器随每次变更递增,可用于确认"变更是否真的被服务感知"。
十二、参考链接
- 官方文档:https://gofeatureflag.org/docs
- relay-proxy API 端点:https://gofeatureflag.org/docs/relay_proxy/relay_proxy_endpoints
- OpenAPI 规范:https://github.com/thomaspoignant/go-feature-flag/blob/main/cmd/relayproxy/docs/swagger.json
- v1.57.2 发布页:https://github.com/thomaspoignant/go-feature-flag/releases/tag/v1.57.2
- 站内篇目:《GO Feature Flag 1.57.2 Ubuntu 22.04 安装指南》、《GO Feature Flag 1.57.2 配置参数详解》