CDN边缘节点的本质是一个反向代理缓存服务器,部署在尽量靠近终端用户的位置。用户在访问静态文件、下载安装包或视频切片时,请求会被调度到边缘节点,如果缓存命中则直接返回本地文件,否则回源拉取并缓存。CentOS凭借稳定的内核和成熟的软件生态,适合作为边缘节点的操作系统。下面从边缘节点工作流程、Nginx缓存配置、回源策略和性能优化几个方面,说明一个基础节点如何落地。

一、CDN边缘节点的工作流程与缓存模型
一个典型的CDN边缘节点会维护本地磁盘缓存,并通过配置的缓存键来标识每个资源。缓存键通常由协议、主机名和请求URI组成。当请求到达节点时,Nginx先计算缓存键,再查找对应的缓存文件。命中缓存时直接返回状态200或304,不会访问源站;未命中时则代理到源站,等待源站响应后,根据响应状态码和缓存策略决定是否写入本地缓存,最后将响应返回给客户端。整个过程对客户端透明,客户端不需要做任何修改。
在自建CDN场景中,边缘节点与中心节点可以形成两层缓存。边缘节点部署在多个地域,中心节点负责统一回源。这样即使边缘节点没有命中,也优先请求中心节点,进一步减少对源站的压力。CentOS系统在这一架构中主要承担稳定的I/O调度、网络参数管理和进程守护。为了获得更好的缓存性能,建议为缓存目录使用独立的SSD或NVMe磁盘,并选择XFS文件系统。
缓存模型分为正向代理缓存和反向代理缓存。本文采用反向代理缓存,因为客户端不需要配置代理地址,所有请求通过DNS解析到边缘节点即可。反向代理缓存的优点是部署简单、对源站地址隐藏,并且可以通过Nginx的丰富指令控制缓存行为。
二、安装Nginx并初始化缓存目录
在CentOS上安装Nginx通常有两种方式:使用系统软件源或从源码编译。对于缓存节点,推荐使用官方或EPEL仓库提供的稳定版本,确保包含proxy_cache相关模块。先执行以下命令安装:
sudo yum install -y epel-release sudo yum install -y nginx sudo systemctl enable --now nginx
安装完成后,需要规划缓存目录。缓存目录不要放在系统盘根分区,避免与系统日志争抢I/O。可以挂载一块独立数据盘到/data,然后创建缓存路径。Nginx的proxy_cache_path指令负责定义缓存目录结构。常用的层级参数levels=1:2表示使用两级子目录,例如缓存文件名前三个字符被拆成/data/cache/f/6c/...,这样可以避免单个目录下堆积数十万文件导致查找缓慢。
缓存键区域使用共享内存保存索引元数据,通过keys_zone指定名称和大小。例如keys_zone=my_cache:50m表示分配50MB共享内存,大约可以缓存几十万到上百万个键,具体取决于键的长度。还需要设置max_size和inactive参数,控制磁盘占用和未访问缓存的最长保留时间。一个基础配置如下:
proxy_cache_path /data/cache levels=1:2 keys_zone=my_cache:50m max_size=20g inactive=7d use_temp_path=off;
这条指令需要放在http块中,而不是server或location块。设置use_temp_path=off可以让Nginx直接写入最终缓存文件,减少跨文件系统拷贝。配置完成后,Nginx启动时会创建缓存目录结构。如果使用了SELinux,需要确保Nginx进程对/data/cache有读写权限,否则会出现缓存写入失败。
三、配置反向代理缓存与回源策略
在server或location块中启用缓存,需要先通过proxy_cache指令引用之前定义的共享内存区域。同时必须设置proxy_pass指向源站地址。一个基础的反向代理缓存配置如下:
server {
listen 80;
server_name cdn.ippipp.com;
location / {
proxy_pass http://origin.ippipp.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache my_cache;
proxy_cache_key "$scheme$proxy_host$request_uri";
proxy_cache_valid 200 302 1h;
proxy_cache_valid 404 1m;
proxy_cache_valid any 10s;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
proxy_ignore_headers Set-Cookie;
proxy_hide_header Set-Cookie;
add_header X-Cache-Status $upstream_cache_status;
}
}这里proxy_cache_key定义了缓存键的计算方式。使用$scheme$proxy_host$request_uri可以覆盖协议、域名和请求路径,避免HTTP与HTTPS共存时产生错误命中。但如果资源会根据查询参数返回不同内容,则必须把$args纳入缓存键,否则会出现缓存串扰。缓存有效期通过proxy_cache_valid按状态码分别设置,200和302响应缓存1小时,404缓存1分钟,其他状态只缓存10秒。这样源站返回错误时不会长时间污染缓存。
回源策略是边缘节点稳定性的关键。proxy_cache_use_stale允许在源站异常时继续提供已过期的缓存内容,避免用户直接看到错误页。参数updating表示当某个缓存正在更新时,其他请求可以直接使用旧缓存;timeout和error分别对应回源超时和连接错误。开启proxy_cache_lock可以防止缓存击穿:同一缓存键同时只有一个请求回源,其余请求等待该请求完成后使用新缓存,能显著降低源站瞬时压力。
Nginx默认对包含Set-Cookie头的响应不进行缓存,但很多源站会为所有响应设置会话Cookie,导致缓存命中率极低。对于纯静态资源,可以通过proxy_ignore_headers Set-Cookie忽略该头,强制缓存;同时使用proxy_hide_header Set-Cookie从返回给客户端的响应中隐藏Set-Cookie,避免上游Cookie污染下游。通过add_header X-Cache-Status $upstream_cache_status可以在响应头中看到缓存状态,方便调试。
四、边缘节点性能调优与命中率监控
缓存节点不仅要正确缓存,还要尽快把数据发送给用户。操作系统层面可以调整TCP参数,Nginx层面开启sendfile和tcp_nopush,让内核直接在内核空间发送文件,减少数据拷贝。对于小文本资源,开启gzip可以有效减小传输体积,但会消耗CPU。基础调优配置如下:
sendfile on; tcp_nopush on; tcp_nodelay on; gzip on; gzip_types text/plain text/css application/json application/javascript image/svg+xml; gzip_min_length 1k; gzip_comp_level 5;
缓存目录的文件系统选择也很重要。XFS对大量小文件的读写性能优于ext4,适合缓存场景。建议将缓存目录挂载参数设置为noatime,减少访问时对inode的元数据写入。对于热点小对象,可以考虑使用tmpfs挂载一部分内存作为缓存索引或临时缓存,但需要权衡内存与磁盘容量。
命中率是评价边缘节点价值最直接的指标。通过响应头中的X-Cache-Status可以快速判断缓存状态:HIT表示命中,MISS表示未命中并已回源,EXPIRED表示缓存过期,UPDATING表示正在更新。生产环境建议在日志中记录该变量。修改log_format增加$upstream_cache_status字段,然后通过脚本统计HIT占比。日志格式示例:
log_format cache '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $upstream_cache_status';当缓存命中率长期低于预期时,需要检查缓存键是否包含变化过快的参数、响应是否被Cookie阻止、缓存有效期是否过短。也可以使用proxy_cache_path提供的purger或第三方模块实现主动清理,配合版本化URL来更新静态资源。最终,一个基础边缘节点可以稳定地将静态资源响应时间从源站数百毫秒降低到本地几毫秒,并大幅节省回源带宽。
在CentOS上搭建CDN边缘节点是一个系统工程,涉及网络、存储、缓存策略和运维监控。本文给出的配置可以作为初始版本,后续还可以增加TLS终端、HTTP/2、限流以及更细粒度的缓存分片。