2026-08-30 09:16:32 +08:00
2026-08-30 09:16:32 +08:00
2026-08-30 09:16:32 +08:00
2026-08-30 09:16:32 +08:00
2026-08-30 09:16:32 +08:00
2026-08-30 09:16:32 +08:00
2026-08-30 09:16:32 +08:00
2026-08-30 09:16:32 +08:00
2026-08-30 09:16:32 +08:00

Config Center

一个按 config-center-etcd-implementation.md 落地的自建配置中心。PostgreSQL 保存编辑态、版本和审计记录;发布事务写入 release 与 outboxworker 再将完整 namespace 快照原子下发到 etcd。Web Console 已接入真实 API不再使用浏览器内存数据。

已实现

  • 应用、环境、命名空间、配置项 CRUD
  • 草稿/已发布值分离,新增、修改、待删除状态与发布 diff
  • PostgreSQL 事务化发布,基于 advisory lock 的并发版本分配;
  • Outbox claim、租约恢复、指数退避、最大重试和 release 状态回写;
  • etcd 完整快照 + __meta 同事务写入;
  • 运行时配置读取与 SSE/gRPC Watch统一使用 etcd MVCC revision支持断线续传与 compact 后全量恢复;
  • 发布历史和“生成新版本”的可追溯回滚;
  • 审计日志查询;
  • 可选 JWT 登录、bcrypt 密码、全局管理员与应用级 viewer / app-owner RBAC
  • IP/CIDR、实例 ID、稳定百分比三类灰度规则支持优先级覆盖
  • Go/Python SDK支持 REST/SSE 与 gRPC transport、自动重连、全量替换和本地文件缓存兜底
  • React Web Console含登录、灰度、用户授权页面、Docker Compose 与本地内存开发模式;
  • Prometheus 指标与告警规则、三副本服务/三节点 etcd Kubernetes 清单、SLO 压测工具。
  • HTTP 延迟直方图/p95 告警、带校验和的数据库 migration 追踪、etcd mTLS 与定时备份维护任务。

快速启动

不安装 PostgreSQL/etcd 也可以启动。未设置连接信息时,服务会使用带演示数据的内存控制面和内存运行时:

make dev

另开终端启动 Web Console

make web-install
npm --prefix web run dev

浏览器访问 http://localhost:5173。HTTP API 默认监听 http://localhost:8080gRPC 默认监听 localhost:9091

完整依赖环境:

docker compose up --build

Compose 会启动 PostgreSQL、etcd、Redis、Config Server 和 Web Console。打开 http://localhost:5173。PostgreSQL migration 会在服务启动时串行执行,并记录在 schema_migrations;已经应用的 migration 若内容被修改,服务会拒绝启动。

启用 Prometheushttp://localhost:9090

docker compose --profile monitoring up --build

配置

环境变量 默认值 说明
HTTP_ADDR :8080 HTTP 监听地址
GRPC_ADDR :9091 gRPC 监听地址
GRPC_TLS_CERT_FILE gRPC 服务端 TLS 证书;与私钥同时配置
GRPC_TLS_KEY_FILE gRPC 服务端 TLS 私钥;与证书同时配置
DATABASE_URL 为空时使用内存控制面
ETCD_ENDPOINTS 逗号分隔;为空时使用内存运行时
ETCD_DIAL_TIMEOUT 5s etcd 连接超时
ETCD_TLS_CA_FILE etcd CA 证书路径;生产环境建议配置
ETCD_TLS_CERT_FILE etcd mTLS 客户端证书路径,必须与私钥同时配置
ETCD_TLS_KEY_FILE etcd mTLS 客户端私钥路径
ETCD_TLS_SERVER_NAME 可选的 etcd 服务端证书名称覆盖
OUTBOX_INTERVAL 500ms outbox 扫描周期
OUTBOX_BATCH_SIZE 50 单次 claim 数量
OUTBOX_MAX_RETRY 12 下发失败最大重试次数
CORS_ALLOWED_ORIGINS http://localhost:5173 允许的 Web Origin逗号分隔
AUTH_ENABLED false 是否启用 JWT 登录与 RBAC
JWT_SECRET HS256 密钥;启用认证时至少 32 个字符
JWT_TTL 8h 登录令牌有效期
BOOTSTRAP_ADMIN_USERNAME admin 首次启动时幂等创建的管理员用户名
BOOTSTRAP_ADMIN_PASSWORD 启用认证时必填,至少 12 个字符
BOOTSTRAP_ADMIN_DISPLAY_NAME Administrator 初始管理员显示名称

可复制 .env.example 后按部署环境调整。认证启用后,除健康检查、登录和 /metrics 外的接口都要求 Authorization: Bearer <token>。初始管理员只会在不存在时创建,不会在重启时覆盖已有密码。生产环境应通过 Secret 管理数据库密码、JWT 密钥和初始密码,并启用 PostgreSQL/etcd TLS。

API

管理面响应统一为 { "data": ... },错误统一为 { "error": { "code", "message" } }

方法 路径 说明
GET/POST /v1/applications 应用列表/创建
PUT/DELETE /v1/applications/{id} 应用更新/删除
GET/POST /v1/environments 环境列表/创建
GET/POST /v1/namespaces 命名空间列表/创建
GET/POST /v1/config-items 配置项列表/创建
PUT/DELETE /v1/config-items/{id} 修改/标记待删除
POST /v1/config-items/{id}/restore 撤销待删除
POST /v1/publish 创建发布版本,返回 202
GET /v1/releases?appId=&nsId=&envId= 发布历史与下发状态
POST /v1/rollback 回滚并生成新版本
GET /v1/audit-logs 审计日志
POST /v1/auth/login 用户登录并签发 JWT
GET /v1/me 当前用户与应用角色
GET/POST /v1/users 用户列表/创建(管理员)
GET/PUT/DELETE /v1/users/{id}/roles[/{appId}] 应用角色管理(管理员)
GET/POST /v1/gray-rules 当前范围灰度规则列表/创建
PUT/DELETE /v1/gray-rules/{id} 灰度规则更新/删除
GET /v1/config?env=&app=&namespace=&ip=&instance= 读取运行时快照并匹配灰度规则
GET /v1/watch?env=&app=&namespace=&ip=&instance= SSE 全量同步与更新事件
GET /metrics Prometheus 指标

认证关闭时服务以开发管理员身份运行,并可用 X-User 记录操作者;认证开启时操作者来自 JWT客户端不能通过请求头伪造。viewer 可以读取应用配置,app-owner 还可以维护命名空间、配置、发布、回滚和灰度规则,全局管理员可管理应用、环境、审计和用户授权。

正式 gRPC 契约位于 api/proto/configcenter/v1/config.proto,提供 ConfigService.GetConfig/WatchConfigAdminService.PublishConfig/RollbackConfig。认证令牌通过 authorization: Bearer <token> metadata 传递。WatchConfig.start_revision 为包含式游标:首次订阅传 0,重连传 last_seen_revision + 1;若历史已被 compact服务端发送最新 FULL_SYNC 后从快照 revision 的下一版本继续监听。详细一致性约束见 docs/adr/0001-runtime-revision-watch.md

灰度匹配

ip 规则接受精确 IP 或 CIDRinstance 规则接受实例 ID 列表;percentage 使用 salt 与实例 ID无实例时使用 IP做稳定哈希同一实例不会随机漂移。多条规则命中时按优先级从低到高覆盖并在响应的 grayRuleIds 中返回命中规则。

发布示例

curl -X POST http://localhost:8080/v1/publish \
  -H 'Content-Type: application/json' \
  -H 'X-User: alice' \
  -d '{"appId":1,"nsId":1,"envId":1,"comment":"enable feature"}'

数据库事务提交后返回 pendingoutbox 写入 etcd 后,GET /v1/releases/{id} 会变为 applied 并带上 etcdRevision

SDK

Go SDK

client, err := configsdk.New(configsdk.Options{
    BaseURL: "http://localhost:8080",
    Env: "PROD",
    App: "order-service",
    Token: os.Getenv("CONFIGCENTER_TOKEN"),
    Instance: "order-3",
    CacheFile: "/var/lib/my-service/configcenter.json",
})
if err != nil { /* handle */ }

_ = client.Load(ctx, "application")
go client.WatchAndSync(ctx, "application")
port := client.GetInt("application", "server.port", 8080)

使用 gRPC transport

client, err := configsdk.NewGRPC(configsdk.GRPCOptions{
    Target: "configcenter.example.com:9091",
    Env: "PROD",
    App: "order-service",
    Token: os.Getenv("CONFIGCENTER_TOKEN"),
    Instance: "order-3",
    CacheFile: "/var/lib/my-service/configcenter.json",
})
if err != nil { /* handle */ }
defer client.Close()

_ = client.Load(ctx, "application")
go client.WatchAndSync(ctx, "application")

Python SDK 位于 sdk/python

from configcenter import ConfigClient

client = ConfigClient(
    "http://localhost:8080", "PROD", "order-service", "/tmp/order-config.json",
    token=os.environ.get("CONFIGCENTER_TOKEN"), instance="order-3",
)
client.load("application")
client.start_background_watch("application")
timeout = client.get("application", "order.timeout.minutes", "30")

Python gRPC transport 需要安装可选依赖 configcenter-client[grpc]

client = ConfigClient(
    "configcenter.example.com:9091",
    "PROD",
    "order-service",
    "/tmp/order-config.json",
    token=os.environ.get("CONFIGCENTER_TOKEN"),
    instance="order-3",
    transport="grpc",
)
client.load("application")
client.start_background_watch("application")

本地缓存采用完整快照和原子 renameConfig Server/etcd 暂时不可用时,进程可以读取上一次成功同步的缓存启动。

开发与验证

make test
make proto-check
go test -race ./...
make build
make web-build
docker compose config
make integration-smoke
make loadtest

核心端到端测试覆盖CRUD → 发布事务 → outbox worker → 运行时读取 → 灰度覆盖与指标;单元/HTTP 集成测试还覆盖 JWT 过期与篡改、应用级 RBAC、多版本回滚和 SDK 鉴权/灰度参数。

压测工具默认验证运行时读取的错误率不超过 1%、p95 不超过 200ms可覆盖目标和阈值

go run ./cmd/loadtest \
  -base-url=http://127.0.0.1:8080 -env=DEV -app=demo-service -namespace=application \
  -token="$CONFIGCENTER_TOKEN" -concurrency=64 -duration=60s -max-p95=200ms

生产部署

deploy/kubernetes/configcenter.yaml 提供三副本无状态 Config Server、三节点 etcd、跨节点调度、PDB、HPA、探针、资源限制和 etcd mTLS。operations.yaml 额外提供 etcd 访问网络策略、每 6 小时快照、每周 defrag 和每日 PostgreSQL 备份。部署前替换镜像与 Origin并创建密钥

kubectl create namespace configcenter
kubectl -n configcenter create secret generic configcenter-secrets \
  --from-literal=DATABASE_URL='postgres://...' \
  --from-literal=JWT_SECRET='至少32位随机密钥' \
  --from-literal=BOOTSTRAP_ADMIN_PASSWORD='至少12位初始密码'
kubectl -n configcenter create secret generic etcd-tls \
  --from-file=ca.crt=/secure/path/ca.crt \
  --from-file=server.crt=/secure/path/server.crt \
  --from-file=server.key=/secure/path/server.key \
  --from-file=peer.crt=/secure/path/peer.crt \
  --from-file=peer.key=/secure/path/peer.key \
  --from-file=client.crt=/secure/path/client.crt \
  --from-file=client.key=/secure/path/client.key
kubectl apply -f deploy/kubernetes/

etcd 服务端证书需覆盖 etcdetcd.configcenter.svc.cluster.local*.etcd-peer.configcenter.svc.cluster.localpeer/client 证书应分别包含 Server Auth/Client Auth 所需用途。备份 PVC 只提供集群内保留生产环境还应把快照异步复制到异地对象存储并定期演练恢复。PostgreSQL 仍建议使用托管高可用或主从方案。

目录

cmd/server                 服务入口
internal/api/httpapi       REST + SSE
internal/api/grpcapi       gRPC 服务、认证拦截器与错误映射
internal/store/postgres    PostgreSQL repository 与 migration
internal/store/memory      本地开发/测试实现
internal/runtime/etcd      etcd 快照与 Watch
internal/outbox            异步下发 worker
internal/watch             同 key Watch 扇出
internal/auth              JWT、密码与应用级 RBAC
internal/gray              灰度规则校验与确定性匹配
internal/metrics           Prometheus 指标
cmd/loadtest               运行时读取 SLO 压测
deploy                     Kubernetes 与监控告警配置
pkg/sdk/go                 Go SDK
pkg/proto                  生成的 Go protobuf/gRPC 代码
sdk/python                 Python SDK
api/proto                  gRPC 契约
web                        React Web Console
Description
No description provided
Readme 257 KiB
Languages
Go 64%
JavaScript 29.5%
Python 4%
Shell 1.2%
Makefile 0.9%
Other 0.3%