Background
这两天被阿里云的CDN广告精准推送到了,看了一下之前买的价格。oss+cdn基础款,5、6年过去了目前也就涨了几块钱,估计双十一/618还能打平。
心动了,果断三下五除二给我的破站安排上。 但是阿里云的自动刷新CDN居然是收费的,好你个增值服务。
刚好我的使用场景已经集成进Drone CI流水线,那就再加一个节点用来同步刷新CDN吧。
Steps
Step1 准备访问密钥
在刷新CDN请求中,需要使用AccessKey ID 和 AccessKey Secret来生成签名,所以这一条要提前做。进入阿里云控制台RAM访问控制中,如果没有角色/用户,可以自行创建。
创建完之后点左侧用户,可以在安全信息管理中获取AccessKey ID 和 AccessKey Secret。
Step2 授予角色CDN访问权限
角色需要有CDN访问权限,才可以进行一系列CDN操作。在权限策略中,搜索CDN,直接添加就好。
Step3 准备阿里云CDN刷新脚本
本质上其实是个GET请求,可以直接使用bash
脚本,利用curl
发起。下面是个示例脚本:
#!/bin/bash
# 阿里云 AccessKey ID 和 AccessKey Secret
ACCESS_KEY_ID="your-access-key-id"
ACCESS_KEY_SECRET="your-access-key-secret"
# 阿里云 CDN API Url
CDN_ENDPOINT="https://cdn.aliyuncs.com"
# CDN 刷新请求的参数
DOMAIN_NAME="your-cdn-domain.com"
OBJECT_PATHS="/path/to/your/content"
# 生成请求签名
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
signature=$(echo -n "GET&%2F&$(echo -n "AccessKeyId=${ACCESS_KEY_ID}&Action=RefreshObjectCaches&DomainName=${DOMAIN_NAME}&ObjectPath=${OBJECT_PATHS}&Timestamp=${timestamp}&Version=2018-05-10" | urlencode)" | openssl dgst -sha1 -hmac "${ACCESS_KEY_SECRET}&" -binary | base64)
# 发起刷新请求
curl -X GET "${CDN_ENDPOINT}/?AccessKeyId=${ACCESS_KEY_ID}&Action=RefreshObjectCaches&DomainName=${DOMAIN_NAME}&ObjectPath=${OBJECT_PATHS}&Timestamp=${timestamp}&Version=2018-05-10&Signature=${signature}"
- AccessKeyId 和 AccessKeySecret:你的阿里云 AccessKey ID 和 AccessKey Secret。
- CDN_ENDPOINT:阿里云 CDN API 请求Url
- DOMAIN_NAME 和 OBJECT_PATHS:需要刷新的 CDN 域名和对象路径。
然后我发现阿里云开发者门户有提供一些高级语言的SDK使用模板,就换成python来写了,可以使用他的调试工具,效率更高些。
这是我的python
脚本:
#!/bin/bash
import time
import json
import os
from aliyunsdkcore.client import AcsClient
from aliyunsdkcdn.request.v20180510.RefreshObjectCachesRequest import RefreshObjectCachesRequest
# 从环境变量获取阿里云的密钥
ACCESS_KEY_ID = os.getenv('ACCESS_KEY_ID')
ACCESS_KEY_SECRET = os.getenv('ACCESS_KEY_SECRET')
print(ACCESS_KEY_ID, ACCESS_KEY_SECRET)
if not ACCESS_KEY_ID or not ACCESS_KEY_SECRET:
raise ValueError("Missing Access Key or Secret")
# 初始化客户端
client = AcsClient(ACCESS_KEY_ID, ACCESS_KEY_SECRET, 'cn-shanghai')
# 构建请求
request = RefreshObjectCachesRequest()
request.set_accept_format('json')
# 设置刷新类型:文件、目录等
request.set_ObjectPath('') # 刷新文件或目录的 URL
request.set_ObjectType('Directory') # 可以是 'File' 或 'Directory'
# 发送请求并获取响应
response = client.do_action_with_exception(request)
response_dict = json.loads(response)
# 打印响应
print(json.dumps(response_dict, indent=4))
Step4 配置Drone CI
在drone.yml
文件中,直接在当前构建流水线中找个合适的位置来运行上面脚本就好。下面是我的配置:
- name: refresh-cdn 🚀
image: python:3.9
commands:
- pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
- pip install aliyun-python-sdk-core aliyun-python-sdk-cdn
- python ./xxx.py
environment:
ACCESS_KEY_ID:
from_secret: aliyun_access_key_id
ACCESS_KEY_SECRET:
from_secret: aliyun_access_key_secret
when:
status: [success]
建议 把 AccessKey ID 和 AccessKey Secret 存储在 Drone 的秘密管理中,而不是直接在 drone.yml中。
等流水线执行完,打开资源看能不能正常访问或者看流水线日志来确认CDN有没有成功刷新。
能正常返回请求id和任务id就是成功了,否则会有错误代码输出。
FAQ
- API 权限:确保你的阿里云账户具有刷新 CDN 缓存的权限。
- 网络问题:确保 Drone CI 环境能够访问阿里云的 CDN 请求URL。
- 签名生成:确保生成的签名正确无误,以避免 API 请求失败
...