# EZ-API (控制平面) EZ-API 网关系统的管理中心和控制平面。 ## 目标 EZ-API 是“控制平面”,负责管理事实来源 (Source of Truth)。 它主要承担: 1. **资源管理**:Master/Key/Provider/Model/Binding/Namespace 的 CRUD 与批量操作。 2. **状态同步**:将配置快照与 Feature Flags 推送到 Redis,供 Balancer 使用。 3. **日志与统计**:日志摄取/统计、操作日志、实时计数回写。 4. **运行配置**:CORS、模型注册表、配额重置等运维能力。 ## 架构设计 控制平面采用三层结构,并主动将状态推送到 Redis。 - **数据库**: PostgreSQL(主库),可选独立日志库(`EZ_LOG_PG_DSN`)。 - **缓存/总线**: Redis(配置快照、实时计数、Feature Flags)。 - **框架**: Gin + GORM。 ## API 端点 ### 基础 - `GET /health` - `GET /api/status/test` - `GET /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/providers`(CRUD + test + fetch-models + 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_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。 | 配置读取优先级:环境变量 > 配置文件 > 默认值。通过 [Viper](https://github.com/spf13/viper) 支持 `./config.yaml`(或 `./config/config.yaml`),也可用 `EZ_CONFIG_FILE` 指定路径。示例: ```yaml 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),否则会出现连接错误 建议先启动基础依赖: ```bash docker compose up -d postgres redis ``` 然后在本地设置必要环境变量(可基于 `.env.example`): ```bash go run cmd/server/main.go ``` ### Docker Compose(推荐) 在 `ez-api` 目录使用自带的 `docker-compose.yml` 拉起完整栈(Postgres + Redis + ez-api + balancer): ```bash cd ez-api docker compose up -d ``` 常用可选变量(写入 `.env`): ```env EZ_ADMIN_TOKEN=admin123 EZ_INTERNAL_STATS_TOKEN=internal123 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 单独运行 ```bash 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` 执行 ```bash go work init go work use ./ez-api ./balancer ./foundation ``` 如果你只使用已发布的 `github.com/ez-api/foundation v0.3.0`(或更高 tag),则不需要 `go.work`。 ### 集成测试 依赖 Docker 与 docker compose,且默认在工作区里与 `balancer` 仓库并列(用于构建镜像)。在仓库内运行: ```bash 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](https://github.com/rs/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。这将高流量的数据平面与关系型数据库解耦。