云服务器+Github Pages双节点托管解决博客访问速度和百度收录问题
- Github Pages + Hugo 搭建静态博客介绍了如何使用Github Pages托管静态网站。
- 使用双仓库+多路解析解决Github Pages无法被百度搜索收录的问题介绍了如何使用Coding Pages和Github Pages双仓库托管静态网站。
- 使用云服务器+Nginx配置静态Web服务器介绍了如何使用云服务器和Nginx搭建静态web服务器托管静态网站。
这三种都属于静态网站(博客)托管方式,下表比较了它们各自的优劣势
网站托管方案 | 国内访问速度 | 国外访问速度 | 是否可以被百度收录 | 是否免费 |
---|---|---|---|---|
Github Pages | 慢 | 快 | 否 | 是 |
双仓库 Github Pages+Coding Pages | 慢 | 快 | 是 | 是 |
国内云服务器 | 快 | 慢 | 是 | 否 |
Coding Pages虽然是免费的,且可以被百度收录,但是其服务不太稳定,访问时延经常能达几秒钟,所以用了一段时间后决定放弃Coding Pages了。Github Pages和国内云服务器这两种方案,如果只使用其中一种,需要面对该方式的缺点。而如果将两种方式整合到一起,可以将它们的优点结合,各自扬长避短。简单来说,就是国内云服务器负责国内访问请求(包括百度爬虫),Github Pages负责国外访问请求。这样网站可以被百度正常收录,国内和国外访问速度也都很快。
云服务器和Github Pages部署请参照使用云服务器+Nginx配置静态Web服务器和Github Pages + Hugo 搭建静态博客这两篇文章,这里不再赘述。
完成云服务器和Github Pages部署后,面临的一个问题是每次更新都需要同时手动更新云服务器和Github Pages,太麻烦了,所以本文设计了一个自动同步的解决方案。
Github Pages与云服务器双节点同步
主要实现思路是每次更新时首先将更新推送到Github Pages仓库,然后触发服务器上的网站更新脚本,使其自动从Github Pages上将最新的网站内容下载到服务器上,覆盖旧的网站文件。借助Git的分支切换功能,可以在瞬间完成网站更新,不会影响到网站的正常访问。
下面假定你的网站域名为www.example.com,服务器上的网站目录为/var/www/www.example.com,请替换为实际的域名和网站目录
Step 1 将服务器网站目录初始化为Git仓库,将远程仓库设置为Github Pages仓库。
sudo cd /var/www/www.example.com
sudo git init
sudo git remote add origin https://github.com/example/example.github.io.git #替换为实际的仓库地址
Step 2:在服务器上使用脚本自动更新网站
编写一个网站更新脚本,在服务器上运行,接收更新指令,收到更新指令后,从Github Pages仓库将最新的网站文件下载到服务器上并覆盖旧的网站文件。
网站更新脚本使用Python实现,代码如下:
#!/usr/bin/env python3
import socket
import os
from datetime import datetime
address=('0.0.0.0',55555)
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(address)
s.listen(1)
log_path = "updater.log"
while True:
sock, addr = s.accept()
sock.send(bytes("updating instruction received!",encoding = "utf8"))
now = datetime.now()
os.system("""echo "----------------{}---------------" >> {} 2>&1 """.format(now,log_path))
os.system("""echo "got updating instruction from {}" >> {} 2>&1 """.format(addr,log_path))
os.chdir("/var/www/www.example.com") # 替换为实际的网站目录
os.system("git fetch --all -v >> {} 2>&1".format(log_path))
os.system("git reset remotes/origin/master --hard >> {} 2>&1".format(log_path))
sock.close()
Step 3:让网站更新脚本长期运行在服务器后台
python3 updater.py & # updater.py替换为实际的脚本名称
Step 4:更新Github Pages的同时触发服务器更新
每次在本地更新网站文件后,首先将更新推送到Gtihub Pages上,然后向服务器上的网站更新脚本发送更新指令,触发服务器更新。更新指令使用TCP协议实现,这里没有使用UDP协议,是因为UDP不保证送达,无法确保更新指令可以送达服务器。
触发脚本内容如下:
#!/usr/bin/env python3
import socket
server_ip = socket.gethostbyname('www.example.com')
addr=(server_ip, 55555)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(addr)
print("server said:",s.recv(1024).decode("utf-8"))
s.close()
Step 5:使用脚本一次性完成所有更新操作(可选)
为了进一步减少操作,可以使用脚本一次性完成服务器和Github Pages仓库更新,脚本内容如下:
#网站内容commit,push
echo "\n--------commit and push to site repository--------"
cd example.github.io #替换为本地的实际网站目录名称
git add --all
message=`date '+%Y-%m-%d %H:%M:%S'`
message="Site update $message"
git commit -m "$message"
git push origin $2 # origin指向Githu Pages仓库
#服务器更新
echo "\n--------trigger updating of Nginx server-----------------"
python3 ../triggerUpdating.py #替换为实际的本地触发脚本路径
每次修改了网站文件后,直接运行脚本即可完成全部更新
bash commit.sh #替换为实际的脚本名字