系统架构
本章从部署拓扑、组件职责、运行时依赖与子系统间数据流等角度,完整描述 Cirrus CDN 的系统架构。
总体架构
Redis 作为各层共享的状态存储与发布订阅总线。
控制与数据平面
| 控制平面 | 数据平面 |
|---|---|
| 配置中心(Redis) | 内容缓存与边缘路由 |
| 分发管道(Redis 发布订阅 + Celery 队列) | 健康检测与自治修复 |
| 调度引擎/区域构建 | 日志回传与指标导出 |
高可用性设计
- 多区域多活(独立边缘节点与权威 DNS 从节点)
- 零中断发布(模板化 Compose/Ansible,蓝绿/滚动)
- 自动容灾(NOTIFY 驱动的从节点 + 健康感知激活)
- 自愈循环(Celery 健康检查驱动
active切换并触发区域重建)
部署拓扑
- 本地(docker-compose)
- 生产(Ansible)
docker-compose.yml 定义本地场景下的编排:
- redis:启用 AOF 的主数据存储。
- api:FastAPI(同时服务静态 Next.js 导出)。
- openresty:宿主网络暴露 8080/8443;Prometheus 在 9145。
- worker 与 beat:Celery worker/beat(Redis 作为 broker/backend)。
- caddy:本地 ACME 目录(开发 CA)。
- acmedns:负责 DNS-01 挑战的 acme-dns。
- nsd:接收隐藏主 NOTIFY 的权威从节点。
- prometheus、grafana、fakedns:运维支撑。
api、worker、beat、caddy、acmedns、nsd 共用 acmetest 网桥与静态 IP 以简化信任与路由。
- 通过
ansible/的清单驱动多主机部署。 - API、worker、边缘节点独立扩缩;NSD 副本提供地域冗余。
- 外置 Redis(托管/集群)与证书存储加固。
- 蓝绿/滚动更新;健康检查门控 DNS 激活。
构建与运行产物
Python 与前端镜像(Dockerfile)
- 第一阶段执行
pnpm build构建 Next.js,并缓存.next产物。 - 第二阶段(
ghcr.io/astral-sh/uv:python3.13-trixie-slim)通过uv sync安装依赖,打包静态导出至/app/static,入口脚本负责修复 CA 信任并启动 Uvicorn。
OpenResty 镜像(openresty/Dockerfile)
- 构建安装
lua-resty-http、nginx-lua-prometheus并编译nginx_cache_multipurge。 - 通过
openresty/conf/nginx.conf.j2渲染端口、解析器、缓存大小、指标 ACL。 - 运行阶段加载 Lua:
access_router.lua、ssl_loader.lua、redis_subscriber.lua。
Prometheus 镜像(prometheus/Dockerfile)
- 选择
prometheus.dev.yml或prometheus.prod.yml;默认抓取 9145 端口与 API/metrics。
配置与状态管理
Redis 是唯一可信源。核心键空间包括:
| 键模式 | 作用 |
|---|---|
cdn:domains(集合) | 所有受管域名。 |
cdn:dom:{domain} | JSON 编码的域名配置(DomainConf)。 |
cdn:nodes(集合) | 已知边缘节点 ID。 |
cdn:node:{id} | 节点 IP、健康计数与激活状态。 |
cdn:cert:{domain} | TLS 完整链与私钥。 |
cdn:acme:{domain} | ACME 注册状态(含 acme-dns 凭据)。 |
cdn:acme:lock:{domain} / cdn:acme:task:{domain} | 证书并发锁。 |
cdn:tokens、cdn:token:{id}、cdn:token_hash:{hash} | 服务令牌注册与索引。 |
cdn:acmeacct:global | 共享 ACME 账号密钥。 |
cdn:acmecertkey:{domain} | 证书私钥缓存。 |
发布订阅通道包括 cdn:cname:dirty 与 cdn:purge。
数据流
- 域名接入
- 节点生命周期与健康
- 缓存清理流程
- TLS 签发与续期
环境
Docker 组合主要面向本地开发;生产环境依赖 just deploy 调用的 Ansible 剧本(见 ansible/)。环境变量(如 CNAME_BASE_DOMAIN、ACME_DIRECTORY、DNS_MASTER_PORT)需按环境调整。
可扩展性考量
- API/服务进程除内存会话缓存外是无状态的,如将会话机制迁移至 Redis,可横向扩容。
- OpenResty 可通过
/api/v1/nodes注册更多节点实现扩容;一致性哈希保证域名在节点 churn 下的稳定性。 - DNS 隐藏主节点仍为单实例;NSD 可横向扩展以满足区域冗余。
- Redis 是关键依赖;生产建议使用托管或集群部署。