对于只有1核心的服务器,跑上mysql简直可以感觉到缓慢速度了。

Head Pic: original, cat ears, beast ears / 雫♡zz - pixiv

当初从最初优化时的发现可交互前耗时爆红开始,我便意识到了这个问题,这种延迟是任何一个在意速度的访客无法忍受的。为了抛弃日渐大头的动态内容渲染耗时,没有什么优化插件我没有试过,也没有什么方法我没有求助过,更没有什么免费的CDN我没有用过。我为cloudflare自选了节点,因为从我听说地理位置与访问速度有直接联系。我......(写不下去了哈哈哈哈)

回归主题,既然加速动态内容(指透过查询数据库来实现的)在1核主机和不花钱的情况下几乎很难做到,那就干脆不要mysql和php了,咱们直接上html静态页面。

但是原问题没有得到妥善处理,新问题又不断出现,直接静态化的话我们总不可能重新再一个个页面手动生成,而且部分依靠动态内容才能实现的东西基本上没指望了。

而我这边花了半天时间基本上解决了上述问题,并且成功实现了静态化,在Google的PageSpeed Insights桌面测试中也顺利拿下了92分,移动端因为js过复杂只有62分。

优势与不足

透过静态化,会有这样的好处:

  • 理论上CC攻击相比于用mysql的1核主机更难攻陷(nginx访问html资源消耗可以说非常低了)
  • CDN可以直接Cache Everything
  • 页面渲染速度会快很多。(少掉了php解析和数据库环节)
  • 可以部署在任何支持静态页面托管的地方(比如拿github pages作备用站,源站被ddos直接切换解析)
  • 等等

但是坏处也是极其明显的:

  • 评论浏览量统计需要依靠其他服务
  • 发布文章不是很方便(简直不方便了)
  • 更新一篇文章,与之关联都要变动
  • 一些需要PHP的插件也会失效(比如追番插件,虽然我也把它静态化了)
  • 等等

所以基本上静态化就是一把双刃剑,全凭诸位操作。

评论没了,没关系,反正也很少有人评论。

浏览次数没了,没关系,浏览人数难道自己心里没底嘛。

所以我就静态化了,并且有了这篇水文。

生成页面

因为是静态页面,所以我们新建一个文件夹,然后把主题中的静态资源复制到这个文件夹,

这里以web和Handsome主题为例:

目前的目录结构:

web/
|_usr/

usr是此主题全部css和js等等静态资源,所以我们直接拷贝过来,并且删除其中的php文件(不要泄露主题)。

然后就是文章了,首先curl命令可以访问https/http,并得到网页源码:

curl https://4o5.xyz > index.html

这样就是把我的主页保存到当前目录下的index.html,然后我们把它放到web目录中。

目前的目录结构:

web/
|_usr/
|_index.html

现在打开浏览器就可以访问到你的网站了,当然有些资源不能加载,因为你是本地文件的方式打开的。

(这里强烈建议在本地跑一个nginx之类的网页服务器,并把你的域名hosts到127.0.0.1观察效果)

这样就解决了网页的问题,~~接下来所有的文章页面分类等等按这个模式一步一步来就好啦!~~

咳咳,要是每个都要手动添加岂不是太痛苦了,所以我写了个java程序:

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.Scanner;

public class Generator {
	public static void main(String[] args) {
		Scanner in = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
		String s,backup,dir;
		String[] delta = new String[1024];
		
		boolean isWin = System.getProperty("os.name").indexOf("Windows") >= 0 ? true : false;
		
		while(in.hasNext()) {
			for(int i = 0;i < delta.length;i++) delta[i] = null;
			dir = "";
			
			s = in.nextLine();
			backup = s;
			
			//Remove https:// or http://
			if(s.substring(0, 8).equals("https://")) s = s.substring(8);//is HTTPS
			else s = s.substring(7); // is HTTP
			
			//split the string via '/'
			delta = s.split("/");
			//System.out.println(delta.length);
			
			if(delta.length == 2 && backup.charAt(backup.length() - 1) == '/') {
				for(int i = 1;i < delta.length;i++) dir += delta[i] + File.separator;
				if(isWin) System.out.println("mkdir " + dir);
				else System.out.println("mkdir -p " + dir);
				System.out.println("curl " + backup + " > " + dir + "index.html");
			}else if(delta.length == 2) System.out.println("curl " + backup + " > " + delta[1]);
			else if(delta.length == 3 && backup.charAt(backup.length() - 1) == '/'){
				for(int i = 1;i < delta.length;i++) dir += delta[i] + File.separator;
				if(isWin) System.out.println("mkdir " + dir);
				else System.out.println("mkdir -p " + dir);
				System.out.println("curl " + backup + " > " + dir + "index.html");
			}else if(delta.length == 3) {
				for(int i = 1;i < delta.length;i++) dir += delta[i] + File.separator;
				if(isWin) System.out.println("mkdir " + dir);
				else System.out.println("mkdir -p " + dir);
				System.out.println("curl " + backup + " > " + dir + delta[1]);
			}
		}
		in.close();
	}
}

看到这样一堆的if else判断,我也很无奈嘛,但如果不会java咋办?没事,我这边提供了编译好的jar文件,你下载来用,并且安装Java(JRE)8就好了。

这个~~脚本~~程序大概就是从命令行读取输入的网址,然后帮你按网址创建目录,并把index.html或者***.html下载到那个目录。

这个程序我临时写的,所以有一些局限:网址中最多只可有两层目录(比如https://4o5.xyz/archives/86/),需要更多自己写脚本吧(捂脸,因为我这边只有两层,还有等等bug。

如果要用这个程序,请参照下面步骤:

  1. 打开cmd/终端,切换到jar文件所在的目录。
  2. 输入java -jar Generator.jar
  3. 然后你看似它不动了,那是因为你还没有输入
  4. 输入一个网址,并按下回车
  5. 然后你会得到几行命令
  6. 然后复制运行命令即可
  7. 如果想要批量,请先复制好大量网址,一行一个
  8. 然后看第1步,并输入java -jar Generator.jar > cmd.txt
  9. 然后粘贴网址,回车,并按下ctrl + Z再回车,结束程序。
  10. 这时候命令就在cmd.txt里面了。

emmm看起来有点麻烦,不过能自己静态化的估计也都会自己写程序了,~~应该不需要我写的bug吧~~。

现在的目录结构:

web/
|_usr/...
|_archives/.../
|_page/.../
...
|_index.html

因为各自永久链接方式不同,所以你的目录结构不一定和我一样。

部署

既然是静态页面,部署就非常方便了。

随便拿个nginx写个server,或者放oss,或者放github、coding pages都可以。

我这边大陆访问直接直连,其余走cloudflare,然后缓存可以设置好久好久(哈哈哈缓存一月),顺手拿github pages 做备用站点,反正源站被ddos一般直接黑洞了(阿里云轻量连提醒都不提醒你了),用台大陆服务器跑个脚本遇到不能访问就切换dns解析,所以被打也无所谓了宕机不超过几分钟。

CC攻击基本上可以说是免疫?因为就单单一个100kb不到的html页面能被C死,emmmm。

后续操作

尽管我们静态化了,但是我们要更新文章的话还是得需要原来得博客框架,所以只要你在发布新文章得时候要再次运行php+mysql+nginx,然后再次生成html页面。

毕竟typecho不是静态博客。

最后修改:2020-02-17 19:21:16