跳到主要内容

边缘交付平台

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 管理请求流程:

  1. 使用 resty.redis 从 Redis 获取域名配置;若 Redis 不可用,则回退到 5 秒的共享字典缓存(ngx.shared.dict_conf)。
  2. 验证配置是否存在;缺失时返回 404
  3. 判断是否开启缓存(cache.enable)。
  4. 将源站定义解析为规范化列表(schemehostportsniweight)。
  5. 应用 conf.upstream_headers 定义的自定义头,除非显式指定,否则不会覆盖 Host
  6. 利用共享字典键(wrr:{domain})实现加权轮询选择源站。
  7. 设置 $origin_host$origin_sni$backend 变量驱动 proxy_pass
  8. 通过 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 计算缓存键,支持通配符清除并与配置的缓存区联动。

TLS 处理

ssl_loader.lua 使用 resty.lrucache 缓存最多 2000 条 SNI 记录,存活 10 秒。握手阶段:

  • 获取服务名(ngx.ssl.server_name())。
  • 尝试从 LRU 读取;未命中则从 Redis 的 cdn:cert:{domain} 哈希拉取 fullchainkey
  • 通过 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

  • 按主机/状态计数请求。
  • 记录请求延迟与上游响应时间直方图。
  • 统计缓存状态(HITMISSSTALE 等)与上游错误。

指标通过 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 前端如何将这些能力呈现给操作人员。