mirror of
https://github.com/EZ-Api/ez-api.git
synced 2026-01-13 17:47:51 +00:00
341b54b18560dd86f58924bac789867d79c544fd
Extract ModelMetricsMap as a named type with documentation comments explaining the map structure and providing examples. Update the TrafficBucket.Breakdown field to use the new type and enhance the GetTrafficChart endpoint description with detailed breakdown field documentation including example usage.
EZ-API (控制平面)
EZ-API 网关系统的管理中心和控制平面。
目标
EZ-API 是“控制平面”,负责管理事实来源 (Source of Truth)。 它主要承担:
- 资源管理:Master/Key/ProviderGroup/APIKey/Model/Binding/Namespace 的 CRUD 与批量操作。
- 状态同步:将配置快照与 Feature Flags 推送到 Redis,供 Balancer 使用。
- 日志与统计:日志摄取/统计、操作日志、实时计数回写。
- 运行配置:CORS、模型注册表、配额重置等运维能力。
架构设计
控制平面采用三层结构,并主动将状态推送到 Redis。
- 数据库: PostgreSQL(主库),可选独立日志库(
EZ_LOG_PG_DSN)。 - 缓存/总线: Redis(配置快照、实时计数、Feature Flags)。
- 框架: Gin + GORM。
API 端点
补充文档(中文):
docs/api.md
基础
GET /healthGET /api/status/testGET /swagger/*any
Internal
POST /internal/stats/flush:Balancer 统计回写。GET /internal/metrics:内部指标。
Admin
/admin/masters(CRUD + batch + manage)/admin/masters/:id/realtime/admin/masters/:id/keys/admin/provider-groups(CRUD)/admin/api-keys(CRUD + batch)/admin/models(CRUD + batch)/admin/bindings(CRUD + batch)/admin/namespaces(CRUD)/admin/logs、/admin/logs/stats、/admin/logs/webhook/admin/features、/admin/operation-logs、/admin/stats
Master
/v1/self/v1/tokens(CRUD)/v1/logs、/v1/logs/stats/v1/stats、/v1/realtime
说明
- Master 的
global_qps默认0表示限流关闭;仅当global_qps > 0才会在数据面生效。
配置说明
| 变量名 | 默认值 | 说明 |
|---|---|---|
EZ_API_PORT |
8080 |
监听端口。 |
EZ_PG_DSN |
host=localhost... |
PostgreSQL 主库 DSN。 |
EZ_LOG_PG_DSN |
`` | 日志库 DSN(可选)。 |
EZ_REDIS_ADDR |
localhost:6379 |
Redis 地址。 |
EZ_REDIS_PASSWORD |
`` | Redis 密码。 |
EZ_REDIS_DB |
0 |
Redis DB。 |
EZ_CORS_ALLOW_ORIGINS |
* |
允许的 Origin 列表(逗号分隔)。 |
EZ_LOG_QUEUE |
10000 |
日志缓冲队列容量。 |
EZ_LOG_BATCH_SIZE |
10 |
单次 DB 写入日志数。 |
EZ_LOG_FLUSH_MS |
1000 |
日志批量刷新间隔(毫秒)。 |
EZ_LOG_RETENTION_DAYS |
30 |
日志保留天数。 |
EZ_LOG_MAX_RECORDS |
1000000 |
日志最大记录数。 |
EZ_LOG_PARTITIONING |
off |
日志分区(off/month/day)。 |
EZ_SYNC_OUTBOX_ENABLED |
true |
CP->Redis 同步失败时启用 outbox 重试。 |
EZ_SYNC_OUTBOX_INTERVAL_SECONDS |
5 |
outbox 重试间隔(秒)。 |
EZ_SYNC_OUTBOX_BATCH_SIZE |
200 |
outbox 单次处理数量。 |
EZ_SYNC_OUTBOX_MAX_RETRIES |
10 |
outbox 最大重试次数。 |
EZ_MODEL_REGISTRY_ENABLED |
false |
模型注册表开关。 |
EZ_MODEL_REGISTRY_REFRESH_SECONDS |
1800 |
模型注册表刷新间隔。 |
EZ_MODEL_REGISTRY_CACHE_DIR |
./data/model-registry |
模型注册表缓存目录。 |
EZ_QUOTA_RESET_INTERVAL_SECONDS |
300 |
配额重置间隔。 |
EZ_INTERNAL_STATS_TOKEN |
`` | 内部统计回写鉴权 token。 |
EZ_INTERNAL_ALLOW_ANON |
false |
允许匿名访问 /internal/* 端点(仅限开发/测试)。 |
安全配置说明
内部端点认证 (/internal/*)
- 默认情况下,
/internal/*端点需要X-Internal-Token头与EZ_INTERNAL_STATS_TOKEN匹配。 - 如果
EZ_INTERNAL_STATS_TOKEN为空且EZ_INTERNAL_ALLOW_ANON=false(默认),所有内部端点请求将返回 401。 - 仅在开发/测试环境设置
EZ_INTERNAL_ALLOW_ANON=true以允许匿名访问。
配置读取优先级:环境变量 > 配置文件 > 默认值。通过 Viper 支持 ./config.yaml(或 ./config/config.yaml),也可用 EZ_CONFIG_FILE 指定路径。示例:
server:
port: 8080
postgres:
dsn: host=localhost user=postgres password=postgres dbname=ezapi port=5432 sslmode=disable
redis:
addr: localhost:6379
db: 0
log:
batch_size: 10
flush_ms: 1000
queue_capacity: 10000
auth:
jwt_secret: change_me_in_production
运行方式
本地运行
运行前需要准备依赖(Postgres + Redis),否则会出现连接错误
建议先启动基础依赖:
docker compose up -d postgres redis
然后在本地设置必要环境变量(可基于 .env.example):
go run cmd/server/main.go
Docker Compose(推荐)
在 ez-api 目录使用自带的 docker-compose.yml 拉起完整栈(Postgres + 日志库 + Redis + ez-api + balancer):
cd ez-api
docker compose up -d
常用可选变量(写入 .env):
EZ_ADMIN_TOKEN=admin123
EZ_INTERNAL_STATS_TOKEN=internal123
LOG_POSTGRES_USER=postgres
LOG_POSTGRES_PASSWORD=postgres
LOG_POSTGRES_DB=ezapi_logs
EZ_BALANCER_LOG_SINK_ENABLED=false
EZ_BALANCER_LOG_SINK_BASE_URL=http://ez-api:8080
EZ_BALANCER_STATS_FLUSH_ENABLED=false
EZ_BALANCER_STATS_FLUSH_BASE_URL=http://ez-api:8080
EZ_BALANCER_STATS_FLUSH_TOKEN=internal123
Docker 单独运行
docker build -t ez-api .
docker run -p 8080:8080 --env-file .env ez-api
本地联合开发(配合 balancer)
- 目录结构建议:
/workspace/下并列放置ez-api、balancer、foundation。 - 初始化本地 Go 工作区(Go 1.20+,不要求提交到任一仓库):在
/workspace执行如果你只使用已发布的go work init go work use ./ez-api ./balancer ./foundationgithub.com/ez-api/foundation v0.3.0(或更高 tag),则不需要go.work。
集成测试
依赖 Docker 与 docker compose,且默认在工作区里与 balancer 仓库并列(用于构建镜像)。在仓库内运行:
cd ez-api
./test/integration.sh
脚本会拉起 docker-compose.integration.yml 中的服务,运行带 integration tag 的 Go 测试,并在完成后清理容器和卷。
测试
- 单元测试:
go test ./...(测试文件与源码同目录,更多约定见TESTING.md)
日志
- 业务代码统一使用标准库
log/slog(logger.Info("msg", "k", v)风格)。 - 输出后端仍为 zerolog(通过
github.com/ez-api/foundation/logging的 slog handler bridge),默认 ConsoleWriter。 - 通过
EZ_LOG_LEVEL控制控制平面的日志等级,配合异步 DB 写入(LogWriter)一起使用。
JSON
- 项目内 JSON 编解码统一走
github.com/ez-api/foundation/jsoncodec(内部使用 Sonic)。
依赖约定
- Control Plane(ez-api)与 Data Plane(balancer)共享一部分“协议约定/基础设施”代码(JSON、日志、provider type 规则),统一沉淀在
github.com/ez-api/foundation。 - 本仓库的
go.mod需要依赖一个可用的foundation版本:发布后建议锁定到v0.3.0(或更高 tag);本地联调可使用go.work(见下文)。
设计决策
- 异步日志: 日志不会立即写入 DB。它们被缓冲在内存中,并分批刷新,以减少 DB IOPS。
- 快照同步: Balancer 不查询 DB,而是由 EZ-API 将 JSON 快照推送到 Redis。这将高流量的数据平面与关系型数据库解耦。
Description
Languages
Go
99.2%
Shell
0.5%
Makefile
0.2%