服务公告

服务公告 > 综合新闻 > CDN:CDN自动化管理

CDN:CDN自动化管理

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

一、前言

搞过的人都清楚,线上出bug第一反应是清CDN缓存,结果发现后台刷新要排队等半小时,批量预热更是做梦。手动操作几十个域名试试?手酸眼瞎还容易点错。本文解决的就是这个痛点:用API把CDN刷新、缓存预热、节点查询全自动化,脚本一跑全搞定。

二、操作步骤

第1步:确认API访问凭证

登录CDN控制台,找到API密钥或AccessKey。别用永久密钥,生产环境必须用临时Token,丢了谁都担不起这个责。

# 以阿里云CDN为例,查看环境变量配置 $ env | grep -i aliyun ALIYUN_ACCESS_KEY_ID=LTAI5tXXXXXXXXXXXXX ALIYUN_ACCESS_KEY_SECRET=YOUR_ACCESS_KEY_SECRET ALIYUN_REGION=cn-beijing

第2步:安装SDK或命令行工具

别自己造轮子写HTTP请求,官方SDK都给你封装好了,直接pip装。

# Python环境 $ pip install aliyun-python-sdk-cdn==2.0.0 # 或者用阿里云CLI工具 $ curl -sL https://aliyuncli.alibaba.com/download/aliyun-cli-linux-latest-amd64.tgz | tar -xz -C /usr/local/bin/ $ aliyun configure set --mode Key --access-key-id ${ALIYUN_ACCESS_KEY_ID} --access-key-secret ${ALIYUN_ACCESS_KEY_SECRET} # 验证安装 $ aliyun cdn DescribeCdnService { "InternetChargeType": "PayByTraffic", "OperationLocks": [], "RequestId": "75c378b8-c4a6-4e2a-9c1a-8b3d9e0f1234" }

第3步:编写批量刷新脚本

核心脚本来了,支持按目录刷新和按URL刷新两种模式。目录刷新会自动带上通配符,比逐个URL靠谱。

#!/usr/bin/env python3 # cdn_refresh.py - CDN批量刷新脚本 import os import time from aliyunsdkcdn.request.v20180510 import RefreshObjectCachesRequest def refresh_urls(client, url_list, refresh_type='File'): """刷新URL或目录""" request = RefreshObjectCachesRequest.RefreshObjectCachesRequest() request.set_ObjectPath('\n'.join(url_list)) request.set_ObjectType(refresh_type) response = client.do_action_with_exception(request) return response def batch_refresh(client, urls, batch_size=100): """分批刷新,防止请求超限""" total = len(urls) for i in range(0, total, batch_size): batch = urls[i:i+batch_size] result = refresh_urls(client, batch, 'Directory' if batch[0].endswith('/') else 'File') print(f"[{i//batch_size + 1}] 提交成功: {len(batch)}条") time.sleep(1) # 限速1秒 return total if __name__ == '__main__': # 示例URL列表 test_urls = [ 'https://www.example.com/css/main.css', 'https://www.example.com/js/bundle.js', 'https://www.example.com/api/v1/data', ] print(f"准备刷新 {len(test_urls)} 个URL")

第4步:创建缓存预热脚本

刷新是把旧内容干掉,预热是把新内容提前推到边缘节点。上线前跑一遍,用户体验直接提升一个档次。

#!/usr/bin/env bash # cdn_preload.sh - 缓存预热脚本 set -e API_ENDPOINT="https://cdn.aliyuncs.com" ACCESS_KEY="${ALIYUN_ACCESS_KEY_ID}" ACCESS_SECRET="${ALIYUN_ACCESS_KEY_SECRET}" preload_urls() { local urls_file=$1 local task_count=0 while IFS= read -r url; do [[ -z "$url" || "$url" =~ ^# ]] && continue response=$(curl -s -X POST "${API_ENDPOINT}" -H "Content-Type: application/x-www-form-urlencoded" -d "AccessKeyId=${ACCESS_KEY}" -d "Action=PushObjectCache" -d "ObjectPath=${url}" -d "ObjectType=File" -d "SignatureMethod=HMAC-SHA1" -d "SignatureVersion=1.0" -d "Timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)" -d "Format=JSON" -d "SignatureNonce=$(uuidgen)" -d "Version=2018-05-10") echo "[$(date '+%H:%M:%S')] 预热: ${url}" ((task_count++)) sleep 0.5 done < "$urls_file" echo "总计提交 ${task_count} 个预热任务" } # 使用示例 # echo -e "https://www.example.com/static/app.js\nhttps://www.example.com/images/logo.png" > urls.txt # ./cdn_preload.sh urls.txt

第5步:验证刷新状态

提交刷新任务后别干等着,得查状态确认完成没。CDN服务商的任务状态有时候延迟较大,耐心点。

$ aliyun cdn DescribeRefreshTasks --TaskId "123456789" --OwnerId "123456789" { "Tasks": { "Task": [ { "TaskId": "123456789", "ObjectPath": "https://www.example.com/index.html", "Status": "Complete", "Process": "100%", "CreationTime": "2024-01-15T10:30:00Z", "CompletionTime": "2024-01-15T10:30:45Z" }, { "TaskId": "123456790", "ObjectPath": "https://www.example.com/api/*", "Status": "Running", "Process": "45%", "CreationTime": "2024-01-15T10:30:00Z", "CompletionTime": "" } ] }, "RequestId": "a8f2d3c4-e5b6-4789-a012-3d4e5f678901" }

第6步:配置定时任务和告警

手动跑脚本不是长久之计,得上cron。再配上钉钉/企业微信通知,刷新失败第一时间知道。

# crontab -e 配置定时任务 # 每天凌晨2点执行缓存预热 0 2 * * * /opt/scripts/cdn_preload.sh /opt/scripts/production_urls.txt >> /var/log/cdn_preload.log 2>&1 # 每周一、三、五刷新静态资源 0 3 * * 1,3,5 /usr/bin/python3 /opt/scripts/cdn_refresh.py --type directory >> /var/log/cdn_refresh.log 2>&1 # 告警脚本 - 检查任务失败并发送通知 #!/usr/bin/env python3 # check_cdn_status.py import subprocess import json import requests WEBHOOK_URL = "https://oapi.dingtalk.com/robot/send?access_token=YOUR_WEBHOOK_TOKEN" def check_failed_tasks(): result = subprocess.run( ['aliyun', 'cdn', 'DescribeRefreshTasks', '--TaskType', 'refresh', '--Status', 'failed', '--PageSize', '10'], capture_output=True, text=True ) data = json.loads(result.stdout) failed = data.get('Tasks', {}).get('Task', []) if failed: message = f"⚠️ CDN刷新失败 {len(failed)} 个任务\n" for task in failed[:5]: message += f"- {task['ObjectPath']}: {task.get('ErrorMessage', '未知错误')}\n" requests.post(WEBHOOK_URL, json={ "msgtype": "text", "text": {"content": message} }) if __name__ == '__main__': check_failed_tasks()

第7步:集成到CI/CD流水线

代码发布后自动触发CDN刷新,这才是正经姿势。Jenkins和GitLab CI都支持,Pipeline里加个步骤就行。

# Jenkinsfile 示例 pipeline { agent any stages { stage('Deploy') { steps { echo '部署应用到服务器...' sh 'ansible-playbook -i inventory/prod.yml playbooks/deploy.yml' } } stage('CDN Refresh') { steps { script { def urls = readFile('/var/jenkins_home/cdn_urls.txt').trim().split('\n') sh """ for url in ${urls.join(' ')}; do aliyun cdn RefreshObjectCaches --ObjectPath "$url" --ObjectType File sleep 1 done """ } } } } post { always { echo '清理工作目录...' } failure { dingTalk accessToken: 'YOUR_DINGTALK_TOKEN', message: 'CDN刷新失败,请检查!' } } }

三、常见问题FAQ

Q:刷新请求被限流了怎么办?

别慌,CDN厂商都有QPS限制,阿里云单用户默认200次/秒,刷新Quota用完只能等第二天重置。解法是提前规划,把刷新任务分散到业务低峰期,比如凌晨2-5点。另一个思路是减少无效刷新,新旧URL没变化就别刷,用CDN的304协商缓存能省不少Quota。

Q:目录刷新和URL刷新有什么区别?

目录刷新会自动匹配该路径下所有资源,URL刷新只针对指定的具体链接。实际用下来,目录刷新成功率更高,但耗时更长(可能30分钟才全部生效),URL刷新快但容易漏掉关联资源。我的经验是:首屏页面用URL刷新保证即时生效,全站静态资源用目录刷新批量处理。

Q:CDN节点IP被源站封了怎么排查?

先用describeCdnRegionAndIsp查询各地区节点的IP段,然后去源站Nginx看日志,找到访问异常的那批IP。常见原因是CDN回源IP段不在源站白名单里,或者触发了源站CC防护。解法是把CDN的IP段加到白名单,或者在Nginx设置连接限速和IP限制规则。

Q:多CDN厂商怎么统一管理?

别指望一个脚本搞定所有厂商,API协议完全不同。实用方案是用Terraform的CDN Provider做配置管理,状态文件记录各厂商的配置。刷新和预热这类高频操作,建议各厂商单独写脚本,用统一的入口脚本调度。再往上一层,可以用多云管理平台比如Cortex或山云,但投入成本较高。

四、总结

CDN自动化管理的核心就三点:API是基础、脚本化是手段、监控是保障。手动操作的时代早就该翻篇了,每次上线前手动清缓存这种事,干一次是经验,干十次就是浪费生命。

核心要点:

  • 用SDK封装好的API,别自己写签名逻辑,容易踩坑
  • 批量操作必须分批限速,否则触发风控直接封禁
  • 刷新和预热是两个概念,上线用刷新,日常维护用预热
  • 定时任务配合告警,失败及时通知,别等用户报障
  • CI/CD集成是标配,代码即交付,交付即生效

延伸阅读:

  • 阿里云CDN API文档:RefreshObjectCaches
  • Cloudflare API v4:批量刷新和自定义缓存规则
  • Nginx变量$upstream_cache_status:精准判断缓存命中状态