服务公告

服务公告 > 综合新闻 > CDN:CDN监控与分析

CDN:CDN监控与分析

发布时间:2026-04-21 15:01

CDN监控与分析实战

一、前言

搞过的人都清楚,CDN那玩意儿配完了不等于完了,客户投诉慢你得能说清楚慢在哪。命中率多少、回源多少、各节点带宽啥情况、哪些请求在回源——这些看不懂,你就是瞎运维。这篇说清楚怎么把CDN的监控和分析玩明白。

二、操作步骤

步骤1:搞定CDN日志开关

# 阿里云CDN - 控制台开启日志下载 # 路径:CDN控制台 → 日志管理 → 访问日志 → 开启 # 腾讯云CDN - 日志配置 # 控制台 → 域名管理 → 日志下载 → 开启日志 # AWS CloudFront - 配置日志 aws cloudfront update-distribution --id EDFDVBD6EXAMPLE --default-root-object index.html

预期输出:日志开关后,一般15分钟内开始生成gz压缩包,每小时一个文件。

步骤2:SSH登录日志服务器拉取样本

# 假设日志在 /data/cdn-logs/ 目录 ssh -i ~/.ssh/your_key.pem root@日志服务器IP cd /data/cdn-logs ls -lh | head -20 # 最近1小时的日志 ls -lth *.gz | head -5

预期输出:

-rw-r----- 1 root root 15M Jan 15 14:00 cdn_access_log_20240115_1400.gz -rw-r----- 1 root root 14M Jan 15 13:00 cdn_access_log_20240115_1300.gz -rw-r----- 1 root root 16M Jan 15 12:00 cdn_access_log_20240115_1200.gz

步骤3:解压并分析基础访问量

# 解压日志 gunzip -c cdn_access_log_20240115_1400.gz | head -100 | cat -A # CentOS/RHEL 安装 awstats(如果需要) sudo yum install -y awstats # Ubuntu 安装 awstats sudo apt-get install -y awstats

预期输出:

101.132.45.67 - - [15/Jan/2024:14:00:15 +0800] "GET /static/css/main.css HTTP/1.1" 200 4523 "https://www.example.com/index.html" "Mozilla/5.0" HIT 106.14.23.89 - - [15/Jan/2024:14:00:18 +0800] "GET /api/user/info HTTP/1.1" 200 1234 "-" "Apache-HttpClient/4.5" MISS

注意最后那列:HIT是命中CDN缓存,MISS是回源请求,HIT越多越好。

步骤4:统计命中率

# 统计HIT/MISS比例 gunzip -c cdn_access_log_20240115_1400.gz | awk '{print $NF}' | sort | uniq -c # 精确计算命中率百分比 gunzip -c cdn_access_log_20240115_1400.gz | awk '{print $NF}' | sort | uniq -c | awk ' { total+=$1 if($2=="HIT") hit=$1 } END { printf "总请求: %d\nHIT: %d\nMISS: %d\n命中率: %.2f%%\n", total, hit, total-hit, (hit/total)*100 }'

预期输出:

45231 HIT 3210 MISS 总请求: 48441 HIT: 45231 MISS: 3210 命中率: 93.37%

低于80%命中率就得查查原因了,大概率是动态内容或者缓存策略没配好。

步骤5:分析回源请求都是什么

# 找出所有MISS的请求URL gunzip -c cdn_access_log_20240115_1400.gz | grep "MISS$" | awk -F'"' '{print $2}' | awk '{print $2}' | sort | uniq -c | sort -rn | head -20 # 分析回源请求的响应状态码 gunzip -c cdn_access_log_20240115_1400.gz | grep "MISS$" | awk '{print $9}' | sort | uniq -c | sort -rn

预期输出:

521 /api/v1/product/list 312 /api/v1/user/cart 156 /api/v1/search/suggest 89 /static/images/banner_2024.png 状态码分布: 200: 2102 304: 856 404: 123 502: 129

404和502得重点关注,502说明源站有问题了,别到时候用户投诉你才发现。

步骤6:带宽和流量分析

# 计算总流量(字节) gunzip -c cdn_access_log_20240115_1400.gz | awk '{sum+=$10} END {print "总流量: " sum/1024/1024 " MB"}' # 按URL统计流量TOP20 gunzip -c cdn_access_log_20240115_1400.gz | awk -F'"' '{url=$2; size=$10; count[url]++; bytes[url]+=size} END {for(u in count) print count[u], int(bytes[u]/1024/1024) "MB", u}' | sort -rn | head -20 # 统计每个节点的带宽消耗(如果有X-Cache-IP头) gunzip -c cdn_access_log_20240115_1400.gz | grep -o "X-Cache-IP: [0-9.]*" | awk '{print $2}' | sort | uniq -c | sort -rn

预期输出:

总流量: 1.27 GB 45231 856MB /static/js/vendor.bundle.js 32100 423MB /static/images/logo.png 12340 156MB /static/css/main.min.css

那个vendor.bundle.js占了850MB流量,想想怎么优化——压缩、合并、CDN预热,能省不少带宽钱。

步骤7:慢请求分析

# 找出响应时间超过2秒的请求(假设第12列是响应时间) gunzip -c cdn_access_log_20240115_1400.gz | awk '$10 > 2000' | head -50 # CentOS/RHEL - 安装 jq 处理JSON格式日志 sudo yum install -y jq # Ubuntu - 安装 jq sudo apt-get install -y jq # 如果是JSON格式日志,解析查看延迟分布 gunzip -c cdn_access_log_20240115_1400.gz | jq '.response_time' | awk 'BEGIN{arr[0]=0;arr[1]=0;arr[2]=0;arr[3]=0;arr[4]=0} {if($1<100) arr[0]++; else if($1<500) arr[1]++; else if($1<1000) arr[2]++; else if($1<2000) arr[3]++; else arr[4]++} END {print "<100ms:",arr[0]; print "100-500ms:",arr[1]; print "500-1000ms:",arr[2]; print "1-2s:",arr[3]; print ">2s:",arr[4]}'

预期输出:

<100ms: 38234 100-500ms: 8567 500-1000ms: 1456 1-2s: 143 >2s: 41 慢请求详情: 103.45.67.89 - [15/Jan/2024:14:23:11 +0800] "GET /api/pay/callback HTTP/1.1" 200 3245 5342ms

超过2秒的41个请求全得查,API回调这类接口延迟高影响的不止是体验,还有可能拖垮整个下单流程。

步骤8:实时监控脚本

#!/bin/bash # 放在 crontab 每5分钟执行一次 LOG_DIR="/data/cdn-logs" ALERT_EMAIL="ops@example.com" HIT_RATE_THRESHOLD=80 # 获取最近1小时的日志 LOG_FILE=$(ls -t ${LOG_DIR}/*.gz | head -1) # 计算命中率 HIT_RATE=$(gunzip -c $LOG_FILE | awk '{print $NF}' | sort | uniq -c | awk '$2=="HIT"{hit=$1} $2=="MISS"{miss=$1} END {printf "%.1f", hit/(hit+miss)*100}') echo "当前命中率: ${HIT_RATE}%" if (( $(echo "$HIT_RATE < $HIT_RATE_THRESHOLD" | bc -l) )); then echo "警告: CDN命中率低于${HIT_RATE_THRESHOLD}%" | mail -s "CDN告警" $ALERT_EMAIL # 记录异常日志 echo "$(date): HIT_RATE=${HIT_RATE}%" >> /var/log/cdn_alert.log fi # 检查502错误 ERROR_502=$(gunzip -c $LOG_FILE | awk '$9==502' | wc -l) if [ $ERROR_502 -gt 50 ]; then echo "警告: 1小时内502错误超过50次,当前: ${ERROR_502}次" | mail -s "CDN 502告警" $ALERT_EMAIL fi echo "监控完成: $(date)"

预期输出:

当前命中率: 91.2% 监控完成: Wed Jan 15 14:05:02 CST 2024

三、常见问题FAQ

Q:CDN命中率挺高的,但用户还是反馈慢,怎么查?

别死盯着命中率,命中率99%也有可能是1%的miss请求拖了后腿。用步骤7的慢请求分析方法,专门看那些响应时间超过1秒的请求。常见原因就几个:源站响应慢(查后端服务RT)、DNS解析慢(CDN节点选的不好)、跨运营商跨区域(看看用户是什么网络)、证书握手耗时(检查TLS版本和cipher suite)。还有个最容易被忽略的——TCP连接复用率低导致的建连开销。

Q:日志格式看不懂,CloudFront和阿里云的格式完全不一样怎么办?

这俩差别大了。CloudFront是自定义格式带JSON字段,阿里云是标准NCSA格式。你得先head -5看看日志长啥样,然后写awk的时候按实际字段位置来。记住一个原则:日志格式再乱,timestamp、status、size、cache-status这几列肯定有,找到对应位置就行。阿里云的日志里HIT/MISS在最后一列,CloudFront的得看x-edge-result-type这个字段。

Q:源站带宽没省多少,钱反而多花了,怎么跟老板解释?

这事儿说清楚很简单:CDN不省源站带宽,省的是你服务器要承载的并发连接数。原来的带宽峰值10Gbps,上了CDN后源站降到2Gbps,但CDN产生的流量账单可能是原来带宽费用的两倍。跟老板算这笔账:2Gbps源站带宽+CDN流量费 vs 原来10Gbps带宽费,哪个便宜用哪个。用户访问的稳定性、延迟改善这些没法直接量化,但投诉少了、业务高峰不挂了这都是CDN的价值。

Q:回源率突然飙高,啥原因?

先别慌,按这个顺序查:1)检查最近是不是上了新功能导致新文件没预热,2)看缓存规则是不是被谁改过,3)查源站是不是在回源时间段有503/504错误导致CDN缓存失效,4)确认下日志里的miss是集中在某些URL还是均匀分布——集中说明是特定资源问题,均匀说明是整体策略问题。还有个容易忽略的:源站设置了no-cache或者CDN的缓存头被覆盖了,用curl -I http://cdn地址 看看cache-control是不是符合预期。

四、总结

核心要点:

  • 日志是CDN监控的根基,开通日志下载是第一步,别省这步
  • 命中率低于80%就得查,90%以上才算健康
  • MISS请求要分类:404/502说明源站问题,API/动态内容说明缓存策略问题
  • 带宽分析能帮你优化大文件,流量TOP10URL得门清
  • 慢请求分析别只看CDN节点延迟,源站RT才是重点
  • 告警脚本要跑起来,别等问题爆发了才登录控制台

延伸阅读:

  • Cloudflare博客:《Understanding CDN Cache Hit Ratios》
  • 阿里云CDN文档:《缓存过期配置最佳实践》
  • AWS re:Invent 视频:《Optimizing CloudFront Performance at Scale》
  • NGINX博客:《CDN Logging and Analysis with ELK Stack》

记住,CDN不是配完就完事的,持续监控才是保证用户体验的关键。那些半夜投诉网站慢的,大概率是监控没做到位。