边缘交付平台
OpenResty 是 Cirrus CDN 的数据平面,通过 Lua 脚本执行按域的路由、缓存与 TLS 终止逻辑。本章介绍配置模板、运行行为、清缓存流程以及边缘层输出的遥测数据。
Nginx 配置模板
openresty/conf/nginx.conf.j2 在镜像构建阶段根据环境参数渲染(见 openresty/Dockerfile)。关键指令包括:
proxy_cache_path——定义共享缓存(node_cache),存储于/data/cache。map指令——依据 Cookie($has_cookie)与 cache-control 头($cc_nocache)决定是否绕过缓存。init_worker_by_lua_file——在每个 worker 中执行init_worker.lua,启动清缓存订阅器并初始化指标。log_by_lua_file——请求结束后调用log_metrics.lua更新 Prometheus 计数。listen块——绑定 HTTP(默认 80)与 HTTPS(默认 443)端口,启用 HTTP/2、QUIC,并在 9145 端口暴露指标与健康检查监听。ssl_certificate_by_lua_file——通过ssl_loader.lua动态加载按域证书。
模板支持在构建时注入解析器地址、缓存大小、worker 连接数与指标访问控制。
访问路由(Lua)
openresty/conf/access_router.lua 管理请求流程:
- 使用
resty.redis从 Redis 获取域名配置;若 Redis 不可用,则回退到 5 秒的共享字典缓存(ngx.shared.dict_conf)。 - 验证配置是否存在;缺失时返回
404。 - 判断是否开启缓存(
cache.enable)。 - 将源站定义解析为规范化列表(
scheme、host、port、sni、weight)。 - 应用
conf.upstream_headers定义的自定义头,除非显式指定,否则不会覆盖Host。 - 利用共享字典键(
wrr:{domain})实现加权轮询选择源站。 - 设置
$origin_host、$origin_sni与$backend变量驱动proxy_pass。 - 通过
ngx.log(ngx.INFO, ...)记录选定后端。
DNS 解析由 Nginx 自身处理(proxy_pass 使用主机名),减少 Lua 负担。
缓存与清缓存机制
- 缓存键包含协议、主机、URI 与
Range头,以支持分段缓存。 proxy_cache_background_update允许在后台刷新缓存同时返回陈旧内容。- PURGE 依赖构建阶段编译的
nginx_cache_multipurge:- API 将命令发布到 Redis 通道
cdn:purge。 redis_subscriber.lua在 worker 0 运行,消费消息并向/cache/purge发送 PURGE,请求头中的Host指定目标域名。cache_multipurge.lua使用nginx_cache_keyfinder计算缓存键,支持通配符清除并与配置的缓存区联动。
- API 将命令发布到 Redis 通道
TLS 处理
ssl_loader.lua 使用 resty.lrucache 缓存最多 2000 条 SNI 记录,存活 10 秒。握手阶段:
- 获取服务名(
ngx.ssl.server_name())。 - 尝试从 LRU 读取;未命中则从 Redis 的
cdn:cert:{domain}哈希拉取fullchain与key。 - 通过
ngx.ssl.parse_pem_cert/parse_pem_priv_key解析 PEM。 - 为当前握手设置证书与私钥。
- 遇到解析或设置失败时,记录 Prometheus 计数器(
metric_ssl_handshake_errors)。
镜像构建时生成的占位证书保证在未配置专属证书前,TLS 握手仍可成功。
指标与日志
init_worker.lua:
- 启动 Redis 清缓存订阅器。
- 初始化 Prometheus 指标(请求量、延迟、缓存命中、上游错误/超时、SSL 错误、上游 RTT)。
log_metrics.lua:
- 按主机/状态计数请求。
- 记录请求延迟与上游响应时间直方图。
- 统计缓存状态(
HIT、MISS、STALE等)与上游错误。
指标通过 9145 端口上的 /metrics 暴露,默认只允许本地访问(可通过 NGX_METRICS_ALLOW 配置)。同一端口提供 /healthz 供 Celery 健康检查。
日志:
- 访问日志写入
/data/access-logs/access.log,由独立的logrotate容器管理。 - 错误日志包含 Redis 连接、配置解析、后端选择等调试信息。
安全控制
- 指标端点默认仅本地可访问,可通过构建参数白名单额外 CIDR。
- 清缓存端点仅允许本地(127.0.0.1)访问;外部清缓存需通过 API。
- OpenResty 容器默认使用宿主网络访问
127.0.0.1:6379的 Redis。生产环境应启用 TLS 或强化网络边界。 - 默认禁止覆盖
Host头,除非在upstream_headers["Host"]中显式指定。
性能考量
- 加权轮询由 Lua 实现;当节点规模扩大时,可考虑迁移至一致性哈希或 Nginx upstream 模块。
- 缓存区大小(
NGX_CACHE_MAX_SIZE)可配置,默认 1 GiB。 proxy_cache_lock通过串行化缓存填充防止缓存雪崩。- 客户端协议支持 HTTP/2 与 QUIC,无需额外配置即可拓展协议覆盖面。
OpenResty 在请求时忠实执行控制平面指令。下一章将介绍 Next.js 前端如何将这些能力呈现给操作人员。