Skip to content
lite-txPublic

About

High-concurrency service gateway and real-time traffic analytics platform built with Envoy, Apache bRPC, and ClickHouse.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

FluxGate

高并发服务网关与实时流量分析平台

FluxGate 为一组内部 HTTP 服务提供统一入口:请求在入口完成命名路由、限流和受控重试,每个最终响应形成结构化流量事件;C++ 采集器异步、可恢复地写入分析存储,查询 API 再按路由、状态码和延迟返回可核对的实时聚合。

当前版本为 0.1.0,面向单机 Docker Compose 的可复现开发与验收。是否达到完整交付门槛只以 docs/ACCEPTANCE.md 及其证据目录为准。

当前权威公开运行为 20260904T194934Z-07759130:在 commit 874eaabe5563578ed3d78fa899a5adfe08c0f8de 的干净工作树上完成无缓存构建、13/13 必需阶段和最终清理,结果为 status=passed、authoritative=true。

它解决什么问题

只把代理、业务服务和数据库启动起来,并不能回答这些运维问题:某条路由是否真的进入了正确服务;一次失败是否按限定策略恢复;被限流的请求有没有进入统计;分析存储短暂不可用后数据是否能追上;聚合计数是否被重放事件放大。

FluxGate 把这些问题收敛为一条可执行闭环:

  1. 所有业务请求从同一个公共 listener 进入;
  2. catalog 与 orders 两条命名路由进入可区分的 C++ 服务;
  3. 网关在指定路由执行本地 token bucket,并只为幂等故障演示路由做一次 5xx 重试;
  4. Envoy 把客户端最终看到的结果追加为 JSONL 事件;
  5. C++ collector 以 checkpoint-after-ACK 方式批写 ClickHouse;
  6. C++ control 服务只暴露受限聚合 API,并用 FINAL 消除 at-least-once 重放造成的逻辑重复;
  7. 自动化验收从公共入口制造真实流量,并交叉核对响应、组件日志、Envoy 计数器和 ClickHouse 行。

产品能力

  • 统一路由:GET /api/catalog 与 GET /api/orders 返回不同服务身份,后端容器不直接暴露到宿主机。
  • 确定性限流:GET /api/limited 使用单 Envoy 进程共享的 local token bucket;冻结参数为容量 2、每 60 秒补充 2 个 token。
  • 受控故障恢复:GET /api/unstable 的第一次上游尝试返回 503,Envoy 最多重试一次,第二次返回 200;只对该幂等 GET 生效。
  • 真实流量事件:入口为每个完成的请求写一行 JSONL,包含 route、最终 status、耗时、上游、尝试次数和字节数。
  • 可靠 C++ 采集:只消费换行结束的完整记录;坏行进入 quarantine;稳定 event_id、批写重试、成功确认后原子推进 checkpoint。
  • 受限实时查询:按 route、status 和 latency 提供 JSON API;不开放任意 SQL,时间窗最长 24 小时。
  • 证据化验收:构建、单测、双路由、限流、一次重试、入库、聚合对照、真实 checkpoint 回退重放、ClickHouse 停机恢复、固定请求数负载和空卷 README smoke 均有自动化入口。

架构

                                host 127.0.0.1:18080
Client ───────────────────────────────────► Envoy
                                               │
                      ┌────────────────────────┼───────────────────────┐
                      │                        │                       │
                route catalog            route orders          analytics routes
                      │                        │                       │
                      ▼                        ▼                       ▼
               catalog C++               orders C++              control C++
               brpc :8080                brpc :8080               brpc :8080
                                                                         │
Envoy ── append JSONL ──► access-log volume ──► C++ collector ───────────┤
                                                   │ batch INSERT        │ FINAL query
                                                   ▼                     ▼
                                               ClickHouse traffic_events

catalog、orders、control 和 collector 由同一个自研 fluxgate_node 二进制按 role 启动。请求转发与事件入库解耦:ClickHouse 暂时不可用时,业务路由仍可服务,JSONL 留在共享卷,collector 保持未确认偏移并重试。

仓库结构

FluxGate/
├── gateway/envoy.yaml                 # listener、routes、限流、重试、JSONL access log
├── src/
│   ├── main.cpp                       # 多 role 进程入口
│   ├── services.cpp                   # 双后端与 analytics/control API
│   ├── collector.cpp                  # tail、批写、重试、checkpoint 状态机
│   ├── core.cpp                       # 事件校验、event_id、fallback 计数与原子状态
│   └── clickhouse_client.cpp           # 基于 brpc Channel 的 ClickHouse HTTP 客户端
├── clickhouse/init/001_schema.sql      # traffic_events 表契约
├── tests/unit_tests.cpp                # event/checkpoint 与 10,001 个 fallback request ID 滚动单测
├── scripts/
│   ├── smoke.py                        # 已启动栈的公共入口 smoke
│   ├── acceptance.py                   # 完整、证据化自动验收
│   └── load_test.py                    # 本机固定请求数负载工具
├── deploy/compose.acceptance.yaml      # 仅验收时暴露 loopback ClickHouse
├── compose.yaml                        # 本地产品栈
├── Dockerfile                          # 固定 bRPC SHA 的多阶段构建
├── docs/ARCHITECTURE.md                # 冻结架构与可靠性语义
├── docs/UPSTREAM_AUDIT.md              # 固定上游审计证据
└── docs/ACCEPTANCE.md                  # 验收项、命令、结果与证据索引

快速开始:PowerShell 空卷复现

前置条件

  • Windows PowerShell;
  • Docker Desktop,支持 Docker Compose v2 的 --wait;
  • Python 3(smoke 只使用标准库);
  • 可访问固定上游源码与容器 registry;
  • 宿主端口 18080、19901 空闲。

第一次构建会从固定 SHA 获取并编译 bRPC,耗时取决于网络、CPU 与 Docker 缓存。

下面的第一次 down --volumes 只清理 Compose 项目 fluxgate 的容器和具名卷,以保证从空数据、空 checkpoint 开始;它会删除此前的 FluxGate 本地事件数据。

# 克隆仓库后,在 FluxGate 仓库根目录执行
$env:FLUXGATE_CLICKHOUSE_PASSWORD = "fluxgate-local-only-change-me"
docker compose down --volumes --remove-orphans
docker compose up --build -d --wait
python scripts/smoke.py

成功时 smoke.py 返回 JSON 且顶层 pass 为 true。它只通过公共入口检查 /api/catalog、/api/orders、一次重试恢复和三个 analytics API,并等待对应事件进入查询结果。

使用完毕后清理容器、空卷和当前 PowerShell 进程中的本地密码:

docker compose down --volumes --remove-orphans
Remove-Item Env:FLUXGATE_CLICKHOUSE_PASSWORD

若启动或 smoke 失败,也应执行上述清理命令。若需要保留本地分析数据,省略 --volumes,但这不再是空卷复现。

HTTP API

默认公共基址为 http://127.0.0.1:18080。所有公开契约当前只接受 GET。

Endpoint 作用 关键响应/边界
GET /healthz 入口和 control liveness 返回 status、component、clickhouse_reachable;HTTP 200 本身不等于完整数据闭环健康
GET /api/catalog 路由到 catalog C++ 服务 JSON 中 service=catalog、route=catalog
GET /api/orders 路由到 orders C++ 服务 JSON 中 service=orders、route=orders
GET /api/limited catalog 业务响应加 route-local 限流 同一 60 秒补充周期的前两个请求放行,后续返回 429 与 x-fluxgate-rate-limited: true
GET /api/unstable 确定性的一次 503 恢复 客户端最终 200;body 中 attempt=2、recovered=true,header 中 x-envoy-attempt-count: 2
GET /v1/analytics/routes 按 route 聚合 route_name、requests、server_errors、rate_limited、avg_latency_ms
GET /v1/analytics/statuses 按最终状态码聚合 status_code、requests
GET /v1/analytics/latency 按 route 返回精确分位数 requests、p50_ms、p95_ms、p99_ms;这些是查询窗口内的观测值,不是产品 SLO

Analytics 公共参数:

  • from、to:Unix epoch 毫秒;默认最近 1 小时,必须有序且跨度不超过 24 小时;
  • route:可选,必须匹配 ^[a-z][a-z0-9_]{0,63}$;
  • status_code:可选,整数 100..599。

PowerShell 示例:

$base = "http://127.0.0.1:18080"
$headers = @{ "x-request-id" = "readme-catalog-1" }
Invoke-RestMethod "$base/api/catalog" -Headers $headers
Invoke-RestMethod "$base/api/orders"

$to = [DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds()
$from = $to - 3_600_000
Invoke-RestMethod "$base/v1/analytics/routes?from=$from&to=$to"
Invoke-RestMethod "$base/v1/analytics/statuses?from=$from&to=$to&status_code=200"
Invoke-RestMethod "$base/v1/analytics/latency?from=$from&to=$to&route=catalog"

先固定 to 再发 analytics 请求,可以避免查询请求自己的 access event 落入被查询窗口。

配置与端口

用户配置

项目 默认/要求 说明
FLUXGATE_CLICKHOUSE_PASSWORD 必填 由 Compose 注入 ClickHouse、collector 和 control;不要放入命令行、镜像或提交到仓库
.env.example 仅本地示例 示例值明确不可用于生产;实际 .env 被 .gitignore 忽略
bRPC source pin 5b61020a9533887bde2d8cc03f9306b6b7104906 同时冻结于 compose.yaml 与 Dockerfile;升级必须重新审计并完整验收
Envoy / ClickHouse images 内容摘要固定 部署按 name@sha256:... 拉取,避免可变 tag 漂移;当前显式选择 linux/amd64

容器内部的 CLICKHOUSE_URL、CLICKHOUSE_USER、CLICKHOUSE_PASSWORD、ACCESS_LOG_PATH、CHECKPOINT_PATH 和 QUARANTINE_PATH 已由 compose.yaml 统一装配,不是公共 API。ClickHouse 使用专用数据库和账号 fluxgate,常规产品栈不把数据库端口暴露到宿主机。

宿主端口

Host 可见性 用途
127.0.0.1:18080 仅 loopback 本地开发公共入口,映射 Envoy 容器 :8080
127.0.0.1:19901 仅 loopback Envoy admin readiness 与验收计数器;不是产品 API
127.0.0.1:18123 仅完整验收时 deploy/compose.acceptance.yaml 临时映射 ClickHouse HTTP,供验收交叉核对

catalog、orders、control、collector 和 ClickHouse 在 fluxgate 内部网络通信。生产部署不能直接照搬开发端口和安全策略。

可靠性语义

JSONL、checkpoint 与 at-least-once

Envoy 把最终下游结果追加到 access-log 具名卷。collector 从 checkpoint 的下一偏移开始读取,只处理以换行结束的完整 JSON;无效完整行写入带偏移与原因的 quarantine,末尾半行留到下一轮。

collector 用 SHA-256(source_id + generation + source_offset + raw_line) 生成稳定 event_id:同一日志代际内的同一行重试 ID 不变,日志 inode 变更或长度回退时则先原子持久化新的 generation 再从偏移 0 读取,避免不同代际的同偏移事件相撞。它以最多 500 行或 512 KiB 组成批次,通过同步 ClickHouse HTTP INSERT ... FORMAT JSONEachRow 写入。只有收到整批成功响应后才以临时文件、fsync 和原子 rename 提交已确认偏移;网络错误、超时或非成功状态使用 250 ms 到 5 s 的有界退避重试。已换行但无效的事件(包括无效 UTC 日历时间)使用 generation + offset + raw 的稳定 quarantine ID 幂等留存,不会因 ClickHouse 确定性类型错误永久卡住后续好事件。

该设计对“已完整写入 JSONL 的事件到 ClickHouse 接收”提供 at-least-once,不是 exactly-once。ClickHouse 表固定为:

ENGINE = ReplacingMergeTree(ingest_version)
PARTITION BY toYYYYMM(event_time)
ORDER BY event_id

服务端可能已提交但 collector 未收到确认时,同一事件会重放。所有产品查询都显式使用 FROM fluxgate.traffic_events FINAL 获取按 event_id 去重后的逻辑行;不依赖后台 merge,也不使用会改变存储状态的 OPTIMIZE TABLE ... FINAL 作为查询或验收前置条件。

限流和重试

  • limited 的 bucket 作用域是单个 Envoy 进程,不是每连接,也不是分布式全局配额;Envoy 重启会重置内存状态。
  • unstable 固定 retry_on=5xx、num_retries=1、per_try_timeout=300ms、route 总超时 1s。
  • 网关删除公共请求携带的 Envoy retry/timeout 控制 header,外部调用方不能把静态策略扩成更多重试或更长超时。
  • 最终 access event 记录客户端看到的 200;第一次内部 503 必须由 catalog 日志和 Envoy retry counter 证明,不能从最终事件反推。

ClickHouse 故障

ClickHouse 停机时,业务入口和两个后端仍可处理请求;collector 不推进未确认 checkpoint,JSONL 在共享卷累积并持续重试。恢复后 collector 追赶,analytics 最终通过 FINAL 看到逻辑去重事件。此保证不覆盖日志写入前掉电、卷永久损坏、磁盘写满、人工删除日志/checkpoint 或跨主机复制;v1 不宣称零丢失或无限缓冲。

运维与安全边界

常用本地诊断:

docker compose ps
docker compose logs --tail 200 envoy collector control
Invoke-WebRequest http://127.0.0.1:19901/ready
Invoke-RestMethod http://127.0.0.1:18080/healthz
  • app 容器以非 root 用户运行,启用只读根文件系统与 no-new-privileges;可写数据限定在具名卷或 tmpfs。
  • ClickHouse 使用专用 fluxgate 账号;密码只通过调用方环境传入。生产环境应改用受管 secret、最小权限分离与轮换机制。
  • 当前 Compose 不包含 TLS、终端用户认证、WAF 或租户鉴权;18080 默认仅绑定 loopback。如需对外暴露,必须先补齐 TLS、认证与边界防护。
  • 本地契约保留调用方提供的 x-request-id,以便跨响应、后端日志和 ClickHouse 事件关联。它不是身份凭据或可信安全属性;互联网入口必须限制长度/字符集,并依据已认证调用方选择接受、重写或拒绝,不能用它单独承担授权或业务幂等。
  • analytics 只执行预定义 SQL;route、status 和时间窗都受验证,不提供任意 SQL 代理。
  • docker compose down --volumes 会删除事件、access log 和 collector checkpoint;执行前确认不需要保留本地证据。

测试与验收

日常 smoke 针对已经启动的栈:

python scripts/smoke.py

最终完整 acceptance 的权威命令是:

python scripts/acceptance.py --clean --requests 1000 --concurrency 32

--clean 会使用独立 Compose project,从该项目空卷开始并执行无缓存构建;随后依次检查环境、固定源码构建与单测、readiness、限流、双后端路由、503 一次重试、ClickHouse 原始行与聚合、三个 analytics API、真实 checkpoint 回退重放与 FINAL 去重、ClickHouse 停机恢复、固定请求数负载,以及再次从空卷启动的 README smoke。脚本不会为抢占端口而杀死其他进程;18080、19901 或验收用 18123 被占用时会明确失败。

每次运行默认在 artifacts/acceptance/public/<run-id>/ 生成带时间戳的响应、日志、查询结果、环境事实和 SHA-256 证据索引。只有当 FluxGate 是独立 Git 仓库、运行前后 HEAD 不变、工作区干净、必需阶段全部通过,且 evidence_privacy.passed=true 时,manifest.json 才会标记 authoritative=true。

验收证据发布

本仓库只放行上述精确 run ID;其 189 个索引证据文件的字节数与 SHA-256 已重新校验,evidence_privacy.passed=true。其他新生成或历史本地证据默认被 .gitignore 排除;只能在审核 HEAD、dirty 状态、隐私门禁和文件哈希后精确放行新 run。逐项结果与限制见 docs/ACCEPTANCE.md。

FluxGate v1 是单 Envoy、单 ClickHouse 节点的本地产品栈,不包含 xDS 控制面、分布式全局限流、多节点数据库、跨地域容灾、Web 大屏、生产发布或 exactly-once。本地验收结论不外推到生产环境。

许可证与上游归属

FluxGate 自研源码采用 Apache License 2.0。运行和构建依赖仍由各自权利人拥有并适用各自许可证;固定源码/镜像、NOTICE 和基础库归属见 THIRD_PARTY_NOTICES.md,源码、许可证和父仓关系的固定证据见 docs/UPSTREAM_AUDIT.md。

核心上游职责仅作归属说明:Envoy 承担代理数据面,Apache bRPC 承担 C++ 服务与客户端框架,ClickHouse 承担分析存储。FluxGate 不复制三个上游完整源码树,不把上游实现或指标主张为本项目原创。

About

High-concurrency service gateway and real-time traffic analytics platform built with Envoy, Apache bRPC, and ClickHouse.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages