
CDN 访问日志记录了全球用户的每一次内容请求,是优化分发策略和提升用户体验的宝贵数据源。本文介绍如何将各类 CDN 平台的访问日志统一接入腾讯云 CLS,通过检索和 SQL 分析挖掘用户行为模式、识别性能瓶颈并优化缓存命中率。
内容分发网络作为互联网流量的最后一公里加速层,每天承载着海量的用户请求——无论是腾讯云 CDN、阿里云 CDN、Cloudflare 等公有 CDN,还是企业自建的边缘节点,它们都完整记录了每个请求的处理过程。这些日志蕴含着丰富的信息维度:用户从哪里来、访问了什么内容、体验是否流畅、是否存在异常行为。对于运营和技术团队而言,深入挖掘这些数据的价值,已经成为提升业务竞争力的重要手段。
传统的 CDN 日志分析往往停留在基础的流量统计层面,如总请求量、带宽消耗等宏观指标。然而,随着业务精细化运营需求的提升,企业需要更深入地了解用户的行为特征和体验状况。将 CDN 日志统一接入腾讯云 CLS(Cloud Log Service)后,可以通过 SQL 查询实现多维度的深度分析,为决策提供数据支撑。CLS 作为一体化可观测 SaaS 服务,提供亿级日志秒级返回的检索性能,配合兼容 SQL 92 标准的统计分析能力(内置 200+ SQL 函数),为 CDN 日志的深度分析提供了轻量而高效的入口。此外,CLS 已上线 AI 助手(支持自然语言生成检索分析语句)和 MCP Server(让大模型直接查日志)等智能化能力,进一步降低使用门槛。
根据 CDN 服务提供商的不同,日志接入 CLS 的方式有所差异:
腾讯云 CDN:在 CDN 控制台的"日志管理"中开启日志投递功能,选择 CLS 作为投递目标,系统会自动将访问日志实时写入指定的日志主题。这是最便捷的接入方式,支持秒级延迟。
其他云厂商的 CDN:对于阿里云 CDN、AWS CloudFront、Cloudflare 等产品,可以通过其日志导出功能将访问日志写入对象存储(如 COS、S3),然后利用 CLS 的数据导入功能定期拉取;或者通过 Webhook/API 将日志实时推送到 CLS。部分 CDN 提供商还支持通过 Kafka 等消息队列中转后再写入 CLS。
自建 CDN 边缘节点:在边缘节点服务器上安装 CLS 提供的 LogListener 采集客户端,配置正则解析规则即可自动采集 Nginx/Apache 访问日志。LogListener 支持增量采集、断点续传和压缩上传,确保日志不丢失且占用带宽最小。对于容器化部署的边缘节点,CLS 还支持通过 DaemonSet 方式采集容器标准输出中的日志。
无论采用哪种接入方式,最终日志都会以结构化格式存储在 CLS 日志主题中,后续的分析方法和 SQL 语句完全一致。
虽然不同 CDN 平台的日志字段名称可能有所差异,但核心信息基本一致。以下以常见字段为例说明:
字段含义 | 腾讯云 CDN | 阿里云 CDN | Cloudflare | AWS CloudFront | 通用/自建 |
|---|---|---|---|---|---|
客户端 IP |
|
|
|
|
|
请求时间 |
|
|
|
|
|
请求 URL |
|
|
|
|
|
状态码 |
|
|
|
|
|
缓存命中 |
|
|
|
| — |
响应大小 |
|
|
|
|
|
回源耗时 |
|
|
|
|
|
边缘节点 |
|
|
|
| — |
User-Agent |
|
|
|
|
|
Referer |
|
|
|
|
|
协议版本 |
|
|
|
|
|
请求方法 |
|
|
|
|
|
在接入日志后,建议在 CLS 索引配置中将这些字段名映射好,并建立相应的键值索引。对于需要进行聚合计算的数值字段(如响应时间、状态码、字节数),记得勾选"开启统计"选项——只有开启统计的字段才能在 SQL 的 avg、approx_percentile、count_if 等聚合函数中使用。
如果同时接入了多个 CDN 平台的日志,可以使用 CLS 的数据加工功能先将各来源的字段名标准化为统一的 Schema(例如统一映射为 client_ip、request_url、status_code、cache_status、response_time 等),然后再进行分析查询。这样可以避免每次写 SQL 都要区分来源的麻烦。
统计访问量最高的 URL 列表,可以直观地看出哪些内容最受用户欢迎:
* | select count(*) as pv, url group by url order by pv desc limit 20按文件类型分类统计,了解不同类型资源的访问分布:
* | select regexp_extract(url, '\\.([^.?]+)(\\?.*)?$', 1) as file_type, count(*) as pv, round(sum(body_bytes_sent) / 1024 / 1024, 2) as traffic_mb group by file_type order by pv desc limit 15regexp_extract 是 CLS 支持的 200+ SQL 函数之一,用于从 URL 中提取文件扩展名。这条语句可以快速识别出图片、视频、CSS、JavaScript 等各类资源的访问量和流量占比,为缓存策略优化提供依据。
按时间粒度统计请求量的变化曲线,揭示用户活跃时段规律:
* | select time_series(__TIMESTAMP__, '1h', '%Y-%m-%d %H:00', '0') as time_window, count(*) as pv group by time_window order by time_window limit 720time_series 函数会按 1 小时间隔对时间轴进行分组,即使某些时间段没有请求也会以零值填充,确保趋势图连续完整。在 CLS 仪表盘中可以将结果可视化为折线图,直观展示工作日与周末、白天与夜晚的流量波动模式。
将访问数据按地理位置聚合,绘制用户分布热力图:
* | select ip_to_country(client_ip) as country, ip_to_province(client_ip) as province, count(*) as pv group by country, province order by pv desc limit 30ip_to_country 和 ip_to_province 是 CLS 内置的 IP 地理位置函数,能够将客户端 IP 映射到国家和地区。配合 CLS 仪表盘的地图图表类型,可以将查询结果直接可视化为全球或全国热力地图。如果发现某个地区的访问量快速增长但节点覆盖不足,就可以考虑在该区域增加边缘节点或调整路由策略。
结合响应时间的地域分布,发现网络质量的区域性差异:
* | select ip_to_province(client_ip) as province, count(*) as pv, round(avg(origin_response_time), 3) as avg_origin_rt, approx_percentile(origin_response_time, 0.95) as p95_origin_rt group by province having pv > 100 order by pv desc limit 20having pv > 100 用于排除样本量过少的地区,避免偶然性数据干扰判断。当某个省份访问量很大但 P95 回源耗时偏高时,就说明该区域的 CDN 线路可能需要优化。
通过解析 User-Agent 字段,统计不同设备类型的占比:
* | select case when regexp_match(http_user_agent, '(?i)mobile|android|iphone') then 'Mobile' when regexp_match(http_user_agent, '(?i)tablet|ipad') then 'Tablet' else 'Desktop' end as device_type, count(*) as pv, round(count(*) * 100.0 / sum(count(*)) over(), 2) as percentage group by device_type order by pv descregexp_match 函数配合正则表达式可以从 User-Agent 中识别设备类型。case when 条件表达式将设备分为移动端、平板和桌面端三类。sum(...) over() 是 CLS 支持的窗口函数,用于计算总数以便得出百分比。这些数据对于前端开发团队的适配工作具有指导意义——当发现移动端用户占比持续上升时,就需要优先保障移动端的加载速度和交互体验。
缓存命中率是衡量 CDN 加速效果的核心指标。以下 SQL 可以快速计算整体和各维度的缓存命中情况:
* | select count(*) as total, count_if(cache_status = 'HIT' OR cache_status = 'hit' OR cache_status = 'RefreshHit') as hit_count, round(count_if(cache_status = 'HIT' OR cache_status = 'hit' OR cache_status = 'RefreshHit') * 100.0 / count(*), 2) as hit_rate from log由于不同 CDN 平台对缓存命中的标识略有差异(HIT、hit、RefreshHit、EXPIRED 等),这里使用 count_if 条件计数涵盖了常见的命中状态。
按 URL 路径分组找出缓存命中率最低的资源:
* | select count(*) as total, count_if(cache_status = 'HIT' OR cache_status = 'hit') as hits, round(count_if(cache_status = 'HIT' OR cache_status = 'hit') * 100.0 / count(*), 2) as hit_rate, url group by url having total > 100 order by hit_rate asc limit 15order by hit_rate asc 将命中率最低的资源排在最前面——这些就是最需要优化缓存策略的对象。可能的原因包括缓存过期时间设置过短、URL 带有动态参数导致无法命中、或者源站返回了 no-cache 头。
按文件类型统计缓存命中率,制定差异化的缓存规则:
* | select regexp_extract(url, '\\.([^.?]+)(\\?.*)?$', 1) as file_type, count(*) as total, round(count_if(cache_status = 'HIT' OR cache_status = 'hit') * 100.0 / count(*), 2) as hit_rate, round(sum(body_bytes_sent) / 1024 / 1024, 2) as traffic_mb group by file_type having total > 50 order by hit_rate asc静态资源如图片、CSS、JavaScript 通常应该有较高的缓存命中率(90% 以上),而动态生成的 HTML 页面命中率较低是正常的。如果发现静态资源的命中率偏低,就需要检查 CDN 的缓存配置是否正确。
CDN 日志中通常包含多个时间维度的字段,可以用来精确分解延迟的来源。以腾讯云 CDN 为例:
edge_response_time — 边缘节点处理时间(从收到请求到发送响应)origin_response_time — 回源耗时(从边缘节点向源站请求到收到响应)tcpinfo_rtt — TCP 往返时延通过对比这些字段,可以快速判断延迟发生在哪个环节:
* | select edge_node_ip, count(*) as requests, round(avg(edge_response_time), 3) as avg_edge_rt, round(avg(origin_response_time), 3) as avg_origin_rt, round(avg(tcpinfo_rtt), 3) as avg_rtt, approx_percentile(edge_response_time, 0.95) as p95_edge_rt group by edge_node_ip having requests > 100 order by avg_edge_rt desc limit 10如果 origin_response_time 占比很高,说明问题主要在源站(源站响应慢导致边缘节点等待时间长);如果 edge_response_time 本身就很低但用户感知慢,则可能是用户本地网络或 DNS 解析的问题;如果 tcpinfo_rtt 偏高,说明网络链路质量不佳。
观察响应时间趋势,及时发现性能劣化:
* | select time_series(__TIMESTAMP__, '5m', '%H:%i:%s', '0') as time_window, avg(edge_response_time) as avg_rt, approx_percentile(edge_response_time, 0.95) as p95_rt, approx_percentile(edge_response_time, 0.99) as p99_rt group by time_window order by time_window limit 288CDN 日志中还可以发现安全相关的信号。识别潜在的 DDoS 攻击或恶意爬虫:
* | select client_ip, count(*) as requests, approx_distinct(url) as unique_urls where __TIMESTAMP__ > now() - interval '5' minute group by client_ip having requests > 1000 order by requests desc limit 10这条语句统计最近 5 分钟内请求次数超过 1000 次的 IP 地址。approx_distinct(url) 计算每个 IP 访问了多少个不同的 URL——如果一个 IP 在短时间内发起大量请求但只访问少数几个 URL,很可能是定向攻击;如果访问了大量不同 URL,则可能是扫描行为。
检测针对特定 URL 的大量 4xx 错误(可能是漏洞扫描):
status >= 400 AND status < 500 | select count(*) as cnt, url, client_ip group by url, client_ip having cnt > 50 order by cnt desc limit 10将这些检测结果保存为定时 SQL 分析并设置告警阈值,就能实现自动化的安全威胁预警。
对于需要持续监控的关键指标(如每分钟请求量、缓存命中率、P95 响应时间),可以使用 CLS 的定时 SQL 功能自动提取并写入指标主题:
* | select count(*) as pv, round(count_if(cache_status = 'HIT' OR cache_status = 'hit') * 100.0 / count(*), 2) as hit_rate, approx_percentile(edge_response_time, 0.95) as p95_rt group by time_series(__TIMESTAMP__, '1m', '%H:%i:%s', '0') order by time_window limit 60在检索分析页面验证好查询语句后,点击"另存为定时 SQL 分析",设置调度周期为 1 分钟,查询时间窗口为 @m-1m,@m(即最近 1 分钟),系统就会每分钟自动执行并将结果写入指定的指标主题。提取到指标主题后的数据可以用 PromQL 查询,无缝对接 Grafana 等监控系统,彻底解决了大时间范围仪表盘超时的问题。
将分析结果固化为 CLS 仪表盘,可以让团队持续关注关键指标的变化。CLS 支持 20+ 种图表类型(时序图、柱状图、饼图、单值图、桑基图、地图、词云等),可以根据不同角色的需求定制专属视图——运维关注缓存命中率和响应时间,运营关注 PV/UV 和地域分布,安全团队关注异常请求和错误率。
定时 SQL 的结果还可以触发 CLS 告警。例如当缓存命中率低于阈值或 P95 响应时间超过限制时自动发送通知:
* | select round(count_if(cache_status = 'HIT' OR cache_status = 'hit') * 100.0 / count(*), 2) as hit_rate where __TIMESTAMP__ > now() - interval '5' minute having hit_rate < 70将此查询设置为告警条件,当 5 分钟内缓存命中率低于 70% 时,系统会通过电话、短信、邮件、企业微信、钉钉、飞书等多种渠道通知值班人员。CLS 的告警支持多维分析附加——告警消息中可以附带按 URL 分组的命中率详情,帮助快速定位具体是哪个资源的缓存出了问题。
CDN 日志量大且增长快,需要根据实际需求制定保留策略。近期日志(如 7 天内)保持标准存储以支持高频检索和分析;历史日志可以沉降到 CLS 低频存储,存储成本可降低约 60%,适合周期性趋势分析和合规审计。对于访问量极大的场景,还可以在前端配置抽样采集,按百分比上报日志以降低整体成本。
想要为 CDN 日志搭建 CLS 分析体系,新用户开通即可领取 10U × 3 个月 免费资源包用于体验,首单特惠最低至 0.8 折起;新老用户购买资源包常规档位最低可享 6.3 折优惠。如需了解更多详情或领取优惠,可访问 腾讯云 CLS 产品页 及 特惠活动页。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。