前情:

在上一篇建站记录系列文章中,我们为博客源服务器配置了CDN加速,但是实际使用中发现,我们推送代码,自动构建生成的新包发到服务器后,我们使用域名访问站点,内容缺没有更新,这是为什么呢?实际上是因为站点资源更新后,CDN没有及时回源进行缓存刷新。

如果对更新的及时性没有特别的需求,完全可以设置CDN定时清除缓存来实现刷新。但是,我要精益求精,实现代码推送后CDN立即刷新,不推送代码就不刷新的功能,不然我浑身难受。

我使用的CDN是腾讯云新一代的EdgeOne,据说是新一代的CDN,多了DDos攻击防御和CC攻击功能,下面就以EdgeOne为例,记录下我的优化过程中。

关键流程:

思路:

开始动手前,需要先理清优化思路,我的优化思路如下:

  1. 在服务器上创建一个service,守护一个bash脚本,监听托管给nginx的静态资源文件夹的变化;
  2. push代码时,静态资源包传到服务器,触发bash脚本,执行nodeJS文件
  3. nodeJS文件中调用腾讯云API,发送请求刷新EdgeOne中博客站点的缓存

动手:

1.编写bash脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/bin/bash

path="/var/www/blog"
LOG_FILE="$path/folderWatcher.log"

# 函数来创建或确认日志文件存在
create_or_verify_log() {
if [ ! -f "$LOG_FILE" ]; then
touch "$LOG_FILE"
echo "Log file created: $LOG_FILE"
fi
}

# 函数来记录错误和信息
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}

# 创建或确认日志文件存在
create_or_verify_log

# 监听文件夹的变化
inotifywait -m -r -e create,modify,delete,move --format "%e %w%f" "$path/to/watched/folder" |
while read -r events; do
# 执行 Node.js 脚本
node "$path/sendRequestToRefreshEO_Cache.js"

# 检查 Node.js 脚本的退出状态
if [ $? -eq 0 ]; then
log "Node.js script executed successfully."
else
log "Error: Node.js script execution failed."
fi
done

2.安装依赖

1
2
sudo apt-get update
sudo apt-get install inotify-tools

安装完成后检查是否安装成功

1
inotifywait -h #打开帮助文档

3.编写node.js测试文件,输入如下内容:

1
console.log('Hellow,world!')

4.启动sh脚本

1
./folderWatcher.sh #启动bash脚本

提示如下信息则说明脚本启动成功:

image-20240202163532004

5.使用systemd守护进程

为了方便调试和提高脚本稳定性,需要编写一个service文件,守护我们的bash进程。

1
2
3
4
5
6
7
8
9
10
11
[Unit]
Description=Folder Watcher Service

[Service]
ExecStart=/var/www/blog/folderWatcher.sh
Restart=always
User=ubuntu #替换为你的用户名
Group=ubuntu #替换为你的用户组

[Install]
WantedBy=default.target

将该服务单元文件保存到 systemd 的服务目录,通常是 /etc/systemd/system/

1
sudo cp folderWatcher.service /etc/systemd/system/

启动服务:

1
sudo systemctl start folderWatcher

启用开机自启动:

1
sudo systemctl enable folderWatcher

查看服务状态:

1
sudo systemctl status folderWatcher

如果弹出如下提示说明服务启动成功

image-20240202165101603

6.测试服务运行情况

在被托管目录创建一个文件

1
touch test.txt

查看service的日志

7.编写nodejs(这里直接复制的腾讯云官方的SDK用例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Depends on tencentcloud-sdk-nodejs version 4.0.3 or higher
const tencentcloud = require("tencentcloud-sdk-nodejs-teo");

const TeoClient = tencentcloud.teo.v20220901.Client;

// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
const clientConfig = {
credential: {
secretId: "SecretId",
secretKey: "SecretKey",
},
region: "",
profile: {
httpProfile: {
endpoint: "teo.tencentcloudapi.com",
},
},
};

// 实例化要请求产品的client对象,clientProfile是可选的
const client = new TeoClient(clientConfig);
const params = {};
client.CreatePurgeTask(params).then(
(data) => {
console.log(data);
},
(err) => {
console.error("error", err);
}
);