跳转至

🚀 Load Proxy

Load Proxy 指部署在多个地理区域的 CDN 边缘节点,以高可用性和低延迟为终端用户提供服务。每个节点可以在内容交付管道中承担一个或多个角色,实现流量路由和内容缓存功能。

🔧 服务器角色

EdgeHit CDN 中的 Load Proxy 节点根据部署配置和地理位置可运行以下一种或两种角色:

  • EdgeHit(CDN角色)— 作为反向代理和缓存服务器,基于 NGINX 实现。负责 HTTP/HTTPS 流量交付和内容加速。
  • EdgeHit DNS(DNS角色)— 作为权威 DNS 服务器,基于 GDNSD(GeoDNS 服务守护进程)组件实现,支持基于地理位置的 DNS 解析。

默认情况下,所有 Load Proxy 节点都启用双重角色。但可以通过角色特定的配置脚本在部署时自定义角色分配。

重要提示:

  • Load Proxy 节点必须始终包含 EdgeHit(CDN)角色,因为它提供了基础运行环境和核心系统组件。

  • 不包含 EdgeHit DNS(DNS)角色的部署是被允许且有时是更优选择,但由于关键服务在安装时的打包和初始化方式,EdgeHit 角色是强制性的。


🧩 通用组件

以下组件安装在所有 Load Proxy 节点上,无论其分配的角色是 EdgeHit 还是 EdgeHit DNS。这些是关键的管控面服务,用于与 EdgeHit Controller 建立安全通信和同步。

这些组件会在 EdgeHit 安装脚本执行时自动安装。

⬇️ Redis 从服务器

每个 Load Proxy 节点运行两个 Redis 实例,每个实例在独立目录中运行,并在管控面中承担特定角色。

  1. config_db 实例
    配置数据库 Redis

  2. 作为 EdgeHit Controllerconfig_db 主实例的副本(从节点)

  3. 持续从管控面同步配置数据
  4. 监听 127.0.0.1:8001,支持通过 redis-cli 进行本地管理访问
  5. 使用 x.509 客户端证书与主实例建立 TLS 加密连接(主实例地址:EdgeHit Controller:9001
  6. 根据节点分配的角色(EdgeHitEdgeHit DNS)获取键值对,动态加载相关配置对象


  1. cache_db 实例
    缓存数据库 Redis

  2. 绑定到 127.0.0.1:8002,可通过 redis-cli 进行本地 CLI 操作

  3. 不对外暴露,确保数据隔离
  4. 被本地后端服务用于预取读取清除缓存内容(基于运行时行为)

安全建议

两个 Redis 实例不实施本地 CLI 访问认证。在使用 Redis-UI 等可能对外暴露这些服务的网页工具时需谨慎——这可能无意中引入安全风险。


🌍 Anycast 健康检查器

部分 Load Proxy 节点部署了 Anycast IP 地址,作为边缘流量的全局入口点。

这些节点使用 BIRD(动态路由守护进程)与上游边界路由器建立 BGP 会话,并宣告其分配的 Anycast 前缀。

为提升可用性和路由准确性,EdgeHit 集成了由 Google 开发的开源 anycast-healthchecker 模块。

🔧 功能

  • 定期检查本地服务健康状态——最重要的是 NGINX 进程。
  • 如果监控的进程故障(例如 NGINX 无响应),它会:
  • 通知 BIRD 撤销 BGP 路由宣告,防止流量继续路由到故障节点。
  • 检测到恢复后,重新宣告前缀,使节点重新加入 Anycast 池。

🧠 此机制确保 自愈式 Anycast 故障转移,意味着流量仅被路由到健康可用的节点。

📦 组件

  • bird — 处理路由宣告的 BGP 守护进程。
  • anycast-healthchecker — 基于 Python 的模块,用于监控服务健康状态并与 BIRD 交互。

📊 Node Exporter

Node Exporter 在部署任何 Load Proxy 实例时自动安装。它向可观测性栈(Prometheus)暴露底层系统指标,支持实时基础设施监控。

  • 监听 0.0.0.0:9100 的 HTTPS 请求。
  • 通过 预共享密钥(PSK)HTTP 认证 保护,该功能由 Node Exporter 服务原生支持。
  • PSK 在安装时随机生成,并安全存储在本地 .env 文件中供系统使用。

Load Proxy 上的 Node Exporter

注意

同一 CDN 网络中的所有 Load Proxy 实例共享相同的 HTTP AUTH PSK 密钥。这简化了与集中式监控系统的安全集成。



🌐 EdgeHit 组件

EdgeHit 角色代表 Load Proxy 节点的核心 CDN 功能。它负责处理 HTTP/HTTPS 流量、执行 SSL 终止、路由到源站服务器以及缓存内容。

配置动态来源于 Redis,其中带有 CDN 键标识符的字符串配置块定义了虚拟主机行为和缓存策略。

🚀 NGINX 引擎

这是 EdgeHit 角色的主要组件,基于 NGINX 构建,并通过 Lua 脚本实现运行时灵活性。

🧠 架构概述:

  • 全局 NGINX 配置包含来自结构化目录树的模块化文件。
  • 运行时,通过 ngx_lua(例如 lua-nginx-module)集成的 Lua 模块从 Redis 获取代表 CDN 虚拟主机定义的键值对。
  • 这些定义作为临时配置块注入 NGINX,避免了重新加载服务器的需求。

🔧 Redis 源的动态配置包括:

  • 用于终止 HTTPS 流量的 SSL 证书(完整链和私钥)
  • 虚拟主机逻辑,包括:
  • 源站服务器地址(IP 或 DNS)
  • 端口、上游协议(HTTP/HTTPS)和健康检查行为
  • 缓存控制规则,包括:
  • 基于通配符和正则表达式驱动的缓存键逻辑
  • TTL 策略和参数处理(例如 ignore_args

🔄 请求处理流程:

  1. 客户端请求到达 Load Proxy 节点(EdgeHit)。
  2. Lua 脚本使用域名作为查找键从 Redis 获取相应配置。
  3. NGINX:
  4. 根据配置的虚拟主机规则匹配请求
  5. 如果已缓存,直接从磁盘提供
  6. 否则,转发到源站,缓存响应并返回给客户端。

🗂️ 缓存目录

  • 所有可缓存响应使用 NGINX 的 proxy_cache 机制持久化在本地。
  • 默认缓存路径为:
    /usr/local/loadproxy/storage/.cdn-cache-default/EdgeHit-cache/
  • 缓存按域名目录存储,每个目录使用域名的 MD5 哈希命名。
  • 在每个域名的缓存目录中,单个 URL 被哈希并存储在嵌套子目录中,遵循 NGINX 的两级缓存键结构。

⚙️ 任务自动化(Python 函数)

EdgeHit 支持自动化缓存预取和清除操作,通过专用的 Python 函数实现。这些脚本与 Redis config_db 实例交互,获取相关配置参数并执行缓存相关任务。

  • 脚本识别缓存目录路径,并使用与 NGINX 缓存键哈希和目录结构镜像的逻辑,确保兼容性。
  • 可以通过向目标源站或缓存端点发送 curl 请求动态更新(预取)删除(清除)缓存内容。
  • 这使得后端控制的缓存操作独立于传入的 NGINX 流量。

注意

通过复制 NGINX 构建缓存文件路径的方式(例如使用 MD5 哈希和 levels=1:2 目录嵌套),Python 脚本可以直接访问或修改缓存文件,与 NGINX 内部存储模型完全对齐。

📅 ClickHouse 客户端(日志传输器)

每个 Load Proxy 节点包含一个安装在主机命名空间中的 ClickHouse 客户端。该客户端负责将遥测数据(如 HTTP(S) 请求日志)转发到 EdgeHit Controller 上托管的中央 ClickHouse 服务器

  • 🔐 认证使用预共享密钥(PSK)执行,在部署时通过环境变量配置。
  • 📡 连接成功后,客户端近乎实时地获取结构化日志数据(例如 NGINX 访问日志)。
  • 🧩 数据在客户端被解析和转换以匹配预期模式,支持准确的分析、报告和计费聚合

🪧 Unbound DNS 解析器

Unbound DNS 解析器部署在每个 Load Proxy 节点上,用于处理内部 DNS 解析,特别是解析 NGINX 配置中引用的源站服务器 IP 地址。

注意

这不是将客户域名映射到 Load Proxy IP 的权威 DNS 服务器——该角色由 EdgeHit DNS(基于 GDNSD)处理。

  • 作为轻量级 Docker 容器运行,限定在主机网络且仅限内部使用。
  • 监听 127.0.0.53,处理来自后端服务(如 NGINX、Redis 同步进程或健康检查)的本地 DNS 查询
  • 配置为精细调整 DNS 缓存行为,包括 TTL 限制和否定缓存生命周期,确保快速一致的解析性能。

通过本地运行 Unbound,系统确保独立、高性能的源站域名解析,不依赖主机 OS 解析器或外部 DNS 源。这提升了内容交付工作流的延迟、可靠性和安全性



🔭 EdgeHit DNS 组件

EdgeHit DNSLoad Proxy 节点承担的 DNS 服务器角色。它作为权威 DNS 服务器,为系统域名和客户配置的 CDN 区域提供服务。

🛸 权威 DNS 服务器

EdgeHit DNS 服务基于开源 gdnsd(GeoDNS 守护进程)构建,并由 RootNetwork 打包为 Docker 容器。它为 CDN 流量路由提供高性能、地理感知的 DNS 解析。

  • EdgeHit DNS 使用 BIND9 式区域文件,以键值对形式存储在 redis_db Redis 实例中。
  • 带有 DNS 特定前缀(例如 DNS:example.com)的 Redis 键包含完整的区域定义,包括 A/AAAA/CNAME 记录、TTL 和地理路由策略。

🌍 基于地理的路由

gdnsd 的关键能力之一是提供地理感知的 DNS 响应

  • DNS 回复可以根据客户端的源 IP 地址(国家、大洲、ASN 等)变化。
  • 这使得智能流量引导成为可能,终端用户被定向到最近的 Load Proxy 节点以减少延迟。

注意

EdgeHit DNS 不支持 EDNS 客户端子网(ECS)。DNS 查询仅基于递归解析器的 IP 解析,而非原始客户端的 IP。

📦 运行时详情

  • 作为 Docker 容器在 Load Proxy 节点上运行。
  • 使用名为 EdgeHit DNS 的容器镜像,发布在 rootnetworks 组织注册表下。
  • 该镜像是开源 gdnsd 项目的自维护分支,增强了 EdgeHit 特定功能。
  • 监听 端口 53(TCP/UDP),响应客户和系统区域的权威 DNS 查询
  • 配置从本地副本 Redis 实例动态加载,支持实时 DNS 区域更新而无需重启容器。
  • EdgeHit DNS 从前缀为 'DNS' 的 Redis 键获取区域数据,关联值包含DNS 主区域文件格式——结构类似于 BIND 式语法,但序列化为 JSON 以便与 EdgeHit 管控面集成。

🩺 DNS 健康记录检查器

EdgeHit DNS 可以通过 ICMP 或 HTTP 请求移除指向宕机服务器的 DNS 记录。原生支持将每个 DNS 记录映射到唯一 ID。然后,EdgeHit DNS 会查询本地或远程进程上的 Web 服务器获取名为 health-dns.txt 的文件,该文件报告所有唯一 ID 的状态。示例如下:

curl http://0.0.0.0:16666/health-dns.txt 

#updated_at=2025-06-13 07:42:50 UTC
#sha256=33e12c5b60fa7226dba05ddd37dd4789446dd25df655aaea44ada16f29923cef
2c2ddfd6-dc6e-42e5-8efc-ea5f9200b6ab,up
9344916f-6aac-472e-8435-64c37f917682,down

健康检查 ID 为 9344916f-6aac-472e-8435-64c37f917682 的 DNS 记录将被撤销,直到状态恢复为正常。

注意

你需要在某些 Load Proxy 端点上部署 health-check 服务,以及LoadUP 组件作为从监控栈服务器抓取信息并以 EdgeHit DNS 理解的文本文件形式呈现的代理。