GO Feature Flag 1.57.2 常用 CLI 与运维命令详解

汇总 GO Feature Flag relay-proxy 1.57.2 的命令行参数、systemd 运维命令与健康、信息、求值、配置、管理接口调用,附日志排查实录与指标观察,全部命令实测。

GO Feature FlagGolangDevOps工程Ubuntu 22.042026/10/28

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 运维命令全景

场景手段关键命令
启停与自愈systemdsystemctl start/stop/restart/status go-feature-flag
存活判断HTTPcurl /health
配置刷新时间HTTPcurl /info
开关求值HTTPPOST /ofrep/v1/evaluate/flags/{key}
开关定义核对HTTPPOST /v1/flag/configuration
手动触发拉取HTTPPOST /admin/v1/retriever/refresh
日志journaldjournalctl -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/* 为辅:前者便于未来切换厂商,后者便于排障时看到更完整的求值元数据。

三、前置条件

  1. 服务已由 systemd 托管并处于 active;
  2. curl 可用;
  3. 操作账号具备 systemctl 与读取 journal 的权限(示例使用 root,口令 q1w2e3r4);
  4. 若配置了 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命中的变体名
reasonTARGETING_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() 观察增速,比直接看绝对值更有意义。

十、注意事项

  1. --config 是唯一启动参数,运维动作不要指望 CLI 子命令;
  2. 版本核对以 /metrics 的 gofeatureflag_build_info 为准,--version 不可用;
  3. 管理接口未配 authorizedKeys.admin 时是锁死状态,不是开放状态;
  4. /health 返回 200 不等于开关正确,必须配一次真实求值;
  5. 日志用 -o cat 便于机器解析,人工看时间线时再加时间戳;
  6. 变更 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

计数器随每次变更递增,可用于确认"变更是否真的被服务感知"。

十二、参考链接