网站预缓存工具,提升网站整体加载速度

由于电信宽带和谐了 443 端口,近期我花了不少时间折腾了下近半年都没瞅一眼的博客。经过一番折腾(详见前文),博客总算可以运行在家里的 NAS 上,整体部署方案如下:

网站预缓存工具,提升网站整体加载速度
图 1. 张戈博客部署架构图

一、预缓存

从上图可以看到,由于中间用于代理转发的腾讯云 CDN 和阿里云 CDN 都是没有缓存的,如果 CloudFlare 的缓存过期,将需要绕过多层链路回源获取网页内容,相比速度就会慢很多。所以,需要在用户访问之前,先将页面缓存到 CloudFlare,这样用户访问就快多了,这就是预缓存的概念。

WordPress 插件 wp-super-cache 以及国内部分 CDN 都提供了预缓存功能,所以,这是一个很实用的优化。不过 CDN 提供的热缓存功能都需要用户手工去提交代码,而预热接口则有诸多限制,如图:

网站预缓存工具,提升网站整体加载速度
图 2. 阿里云 CDN 的预热接口文档

相比于这些限制、复杂度,本文分享的预缓存工具就简单粗暴多了,直接模拟浏览器定期访问来实现预缓存,无任何限制!

温馨提示:只要启用了缓存的网站,都可以用到预缓存优化!

其实之前在博客也分享过一个预缓存 Shell 脚本,确实也可以用,就是效率太低,而且不能指定源站来缓存(除非改造下),于是花了点时间重新写了一个 Python 版本,支持异步、并发请求网页实现预缓存,而且支持指定具体的主机 IP+端口,从而可以支持多 CDN、本地缓存等复杂场景。

下面简单介绍下这个新工具的原理及使用方法。

二、工作原理

和之前分享的 Shell 版本一样:工具会模拟浏览器对网站地图 sitemap.xml 中的网址进行请求,从而实现这些网页的预缓存。当然前提是你的网址启用了静态缓存或者开启了 CDN 全站缓存,启用缓存的相关教程可以参考前文:

在相同原理的基础上,这次的工具也增强了一些特性,请继续往下看使用说明。

三、使用说明

1、基于 Docker 运行

熟悉 Docker 的朋友可以基于 Docker 容器来跑这个工具(Docker 安装参考前文),依赖插件都已经集成好了,就不需要入侵本地环境了,命令如下:

docker run --rm --net=host -ti jagerzhang/pre-cache:latest \
    --sitemap=https://zhang.ge/sitemap.xml \
    --cacheheader=cf-cache-status

如果是拉取 DockerHub 的速度太慢,也可以先在本地编译 Docker 镜像,再跑上面的命令,编译方法如下:

git clone https://github.com/jagerzhang/Pre-cache.git
cd Pre-cache
docker build -t jagerzhang/pre-cache:latest ./

2、基于代码运行

基于代码运行需要先初始化一下 Python 环境,按装工具所依赖的组件,具体命令如下:

git clone https://github.com/jagerzhang/Pre-cache.git
cd Pre-cache
yum install -y python-pip
pip install --upgrade pip -i https://mirrors.aliyun.com/pypi/simple/
pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/

依赖环境初始化完成后,执行如下命令开始预缓存:

python pre_cache.py \
   --sitemap=https://zhang.ge/sitemap.xml \
   --cacheheader=cf-cache-status

3、基于对象引用

同样工具也支持在其他 Python 脚本中来作为对象引用,示例代码如下:

from pre_cache import PreCache
pre = PreCache(sitemap="https://zhang.ge/sitemap.xml",
                   host=None,
                   size=10,
                   timeout=10,
                   cache_header="cf-cache-status",
                   user_agent="Pre-cache/python-requests/2.22.0",
                   verify=False)
pre.start()        

4、执行结果

正常执行结果如下所示:

[root@localhost ~]# docker run -ti --net=host jagerzhang/pre-cache:latest --host=127.0.0.1:8443 --sitemap=https://zhang.ge/sitemap.xml --cacheheader=x-cache-redis
站点地图:https://zhang.ge/sitemap.xml
指定主机:127.0.0.1:8443
并发数量:20
超时时间:10 秒
缓存标识:x-cache-redis
UA 标识:Pre-cache/python-requests/2.22.0
预缓存开始:
---------------------------------------------------------
缓存标识头缺失页面:https://zhang.ge/5072.html 
不可缓存页面:https://zhang.ge/roll.html 缓存标识头:X-Cache-Redis: BYPASS
不可缓存页面:https://zhang.ge/goodarticles 缓存标识头:X-Cache-Redis: BYPASS
不可缓存页面:https://zhang.ge/tag/google 缓存标识头:X-Cache-Redis: BYPASS
---------------------------------------------------------
预缓存完成,页面总数:897,耗时 16 秒
已被缓存页面数:893
不可缓存页面数:3
缓存标识头缺失页面数:1

Ps:为了让大家快速看到效果,这里就直接贴张戈博客的预缓存命令了,大家浅尝辄止,就不要无聊扫我的网站了。

上面就是快速尝鲜使用这个工具的方法,下面详细介绍工具参数。

5、参数介绍

–help、-h 参数打印帮助信息:

[root@localhost ~]# python pre_cache.py --help
usage: pre_cache.py [-h] -s SITEMAP [-S SIZE] [-t TIMEOUT] [-H HOST]
                    [-c CACHEHEADER] [-U USERAGENT] [-v VERIFY]

网站预缓存脚本,支持使用 CDN 或本地有静态缓存的网站.

optional arguments:
  -h, --help            show this help message and exit
  -s SITEMAP, --sitemap SITEMAP
                        网站地图 sitemap 地址
  -S SIZE, --size SIZE  并发请求数量,默认 20
  -t TIMEOUT, --timeout TIMEOUT
                        单个请求的超时时间,默认 10s
  -H HOST, --host HOST  指定真实主机,比如 127.0.0.1:8080
  -c CACHEHEADER, --cacheheader CACHEHEADER
                        缓存标识,比如: x-cache
  -u USERAGENT, --useragent USERAGENT
                        指定 UA 标识,默认 Pre-cache/python-
                        requests/__version__
  -v VERIFY, --verify VERIFY
                        是否校验 SSL,默认不校验     
  -d, --debug   是否显示 Debug 信息, 默认关闭  

其他参数如帮助信息所示,简单说明如下:

参数 必须 默认值 说明
–sitemap / -s 指定网站地图 sitemap 文件网址,必须为 xml 文件格式。
–cacheheader / -c 指定响应头里面的缓存标识名称,比如 CF 为 cf-cache-status,不指定不影响功能,但是无统计信息。
–host / -H 指定具体主机来访问页面,即绕过 CDN 或代理访问真实主机,支持端口,比如 127.0.0.1:8080。
–size / -S 20 指定预缓存时并发访问的数量,并非越大越好,需要自定测试整体耗时来得出最佳值。
–useragent / -u 见说明 自定义请求时的 User-Agent 标识来模拟客户端,默认值:Pre-cache/python-requests/xx.xx。
–timeout / -t 10 指定单个请求的超时时间,默认 10 秒。
–verify / -v False 是否验证 SSL 证书,保持默认即可,开启验证可能无法支持指定–host 来预缓存。
–debug / -d False 是否显示 Debug 信息, 默认关闭,运行时加入 –debug 参数即可打开

这里,挑几个比较核心的参数继续展开说明下。

–sitemap

整个工具的原理是先请求 sitemap 内容,然后对 sitemap 里面的 url 进行爬扫,因此–sitemap 这个参数是必须参数,指定为网站的 sitemap 地址即可,比如:–sitemap=https://zhang.ge/sitemap.xml,需要注意的是这个 xml 必须是 xml 格式,这里推荐使用我博客之前分享的sitemap 纯代码版本。如果是用插件生成的,可能是多个 sitemap 地址,然后有一个汇总的 sitemap 导航,这种情况的话只需要将这个参数指定为具体的分页 sitemap 地址,且需要分别执行多次。

–cacheheader

这个参数是指定网页被缓存后,Header 头部中的 HIT 标识,常见的头部标识如下:

缓存类型 头部名称 常见值
Nginx 缓存 X-Cache/或自定义 HIT,MISS,EXPIRED,BYPASS
CloudFlare cf-cache-status HIT,MISS,EXPIRED,DYNAMIC
腾讯云 CDN x-cache-lookup HIT/MISS/EXPIRED/BYPASS From Upstream/XXX
阿里云 CDN X-Cache HIT,MISS,EXPIRED,BYPASS

如果不在上述类别或者自定义过,我们也可以通过浏览器开发者模式查看,方法为:浏览器打开页面–>F12–>NETWORK–>刷新–>查看响应头:

网站预缓存工具,提升网站整体加载速度
图 3. 查看头信息

一般出现有 HIT,MISS,EXPIRED,BYPASS 值的就是我们这个参数需要指定的名称,比如图中的 cf-cache-status,那我们运行工具的时候只需要指定为 –cacheheaer=cf-cache-status 即可。当然,如果有多层缓存时,需要注意甄别。比如 CDN 有个 HIT,本地 Nginx 也有个 HIT,那么看你需要缓存那个就指定哪个了。

–host

这个参数就比较实用了,可以指定真实 IP 来访问网页,且支持自定义端口。比如 –host=127.0.0.1 或 –host=127.0.0.1:8080,指定后工具将会请求到指定的主机进行资源拉取实现指定节点预缓存。比如张戈博客开了 CDN 缓存同时本地也开启了 Nginx 缓存,我就可以如下分 2 步执行:

# 先本地预缓存:
python pre_cache.py \
   --sitemap=https://zhang.ge/sitemap.xml \
   --host=127.0.0.1:8443 \     # 指定本地 WEB 服务监听的 8443 端口
   --cacheheader=x-cache-redis # 我这边自定义了一个缓存头

# 然后 CDN 预缓存(这里需要伪造一下浏览器 UA,否则 CloudFlare 拦截大部分请求,当然伪造后也会有少量拦截,影响不大):
python pre_cache.py \
   --sitemap=https://zhang.ge/sitemap.xml \
   --cacheheader=cf-cache-status \
   --useragent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"

其他参数比较简单,就不展开赘述了,看上文的表格即可。

6、定时任务

上文已经详细介绍了如何运行这个工具,那接着我们需要通过 crontab 添加一个定时任务,定期进行预缓存。比如我博客需要在本地、百度云加速以及 CloudFlare 3 个层面做预缓存,那么就将基于 Docker 运行的命打包成 shell 脚本,并按照先预缓存本地,然后再缓预存 CDN 的顺序:

#!/bin/bash
source /etc/profile
# 注意:通过 crontab 执行 docker 是没有 tty 终端的,所以下面的 docker 的参数不能有-t
# 本地预缓存
docker run --net=host --rm -i \
    jagerzhang/pre-cache:latest \
    --sitemap=https://zhang.ge/sitemap.xml \
    --cacheheader=x-cache-redis
    --host=127.0.0.1:18443 \
    --size=50
    
# 百度云加速预缓存
docker run --net=host --rm -i \
    jagerzhang/pre-cache:latest \
    --sitemap=https://zhangge.net/sitemap.xml \
    --cacheheader=cf-cache-status \
    --size=50 

# CloudFlare 预缓存
docker run --net=host --rm -i \
    jagerzhang/pre-cache:latest \
    --sitemap=https://zhang.ge/sitemap.xml \
    --cacheheader=cf-cache-status \
    --size=20 \
    --useragent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"

然后在系统 crontab 里面添加一个定时任务,每小时执行一次:

# 进入定时任务编辑,插入如下命令行:
[root@localhost ~]# crontab -e 
* 1 * * * bash /domp/opt/pre_cache.sh >/dev/null 2>&1
# :wq 保存退出

这样就能实现定期网站预缓存了,其他网站可以参考添加。

四、工具反馈

以上就是这个工具的详细介绍了,整体设计、代码逻辑都比较简单,目前这个工具已经上传到了Github,并且在Docker Hub制作了 Docker 镜像,大家使用后觉得实用的话可以给个星星,有什么建议也可以留言或 github 提 issue:

EnJoy it!

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇