站点维护记录:从 2.6 秒到 0.13 秒

可爱的站长 发布于 9 小时前 44 次阅读 1057 字 web


这几天博客挂了整整六天,全站 500,报的是那句经典的 Error establishing a database connection。今天总算修好了,顺手做了一轮优化,记录下来免得下次再踩。

一、为什么会挂

表面看是数据库连不上,实际是三个问题叠在一起。

1. 磁盘被备份撑爆了

宝塔面板的自动备份每天生成一份,每份 937 MB,攒了 38 份——29 GB。40 GB 的盘直接写满。

磁盘 100%
  → dockerd 报 mkdir /var/lib/docker/tmp: no space left on device
  → Docker 起不来
  → wordpress_db 容器不在
  → PHP 连不上 db:3306
  → 全站 500

2. 目录权限被改成了 600(这个最隐蔽)

清完磁盘、Docker 起来之后,MySQL 还是崩溃循环:

[ERROR] --initialize specified but the data directory has files in it. Aborting.

看起来像数据损坏,其实不是。数据目录整棵树的权限被改成了 600,连目录也是。

目录少了 x 位就无法进入,MySQL 的启动脚本 [ -d "$DATADIR/mysql" ] 检测失败,误判成"全新数据库",于是尝试初始化,然后被"目录非空"拒绝,abort。

教训:drw------- 对目录来说是个废权限。文件 600 没问题,目录 600 等于不可用。

3. LiteSpeed Cache 在 nginx 上空转

修好之后发现首页还是 2.6 秒。定位过程:静态文件 12 ms、REST 接口 73 ms,只有首页慢。

装了个临时探针记录各阶段耗时,发现 wp_footer 在 0.117 秒就渲染完了,但总耗时 2.65 秒——页面早就生成好,后面又凭空烧掉 2.5 秒。

A/B 测试:

启用 LiteSpeed Cache:首页 2.60s
停用 LiteSpeed Cache:首页 0.13s

它是给 LiteSpeed 服务器写的,而这里跑的是 nginx。缓存从来没真正生效过(缓存目录都不存在),但每次请求仍要跑一遍 UCSS / CSS 合并压缩流程,纯 CPU 空转。

二、优化做了什么

项目 之前 之后
首页 TTFB 2.60 s 0.13 s
图片(重压缩部分) 315.5 MB 46.1 MB
uploads 目录 419 MB 150 MB
磁盘占用 39G / 40G 12G / 40G
>5 MB 的大图 14 张 0 张
  • 图片:最长边限制 1920px、JPEG 质量 82 + progressive、PNG 大图量化到 256 色。原地重压缩,文件名不变,不断引用。最大那张 27.5 MB 压到 1.2 MB(96%)。
  • 域名统一:www 和非 www 混用会让缓存和登录态分裂,统一成不带 www,旧地址 301 跳转。
  • 静态资源缓存:之前图片只缓存 1 分钟,等于每次访问都要回源,现在改成 30 天。
  • 安全头:补上 HSTS / X-Content-Type-Options / Referrer-Policy / Permissions-Policy。
  • 清理指纹:删掉 readme.html、license.txt,屏蔽 xmlrpc.php,关掉 TLS 1.1。
  • 数据库:缓冲池 128M → 512M,3307 端口不再映射到公网。

三、nginx 的两个坑

加安全头的时候发现配置里明明写了 HSTS,但外网就是收不到。原因是 add_header 的继承规则:

  1. location 里一旦出现 add_header,就会覆盖掉 server 层的所有 add_header;
  2. if 块里的 add_header 同样会覆盖同层级的其他 add_header。

宝塔生成的模板里有这么一段:

if ( $static_file3WsVfDPT = 0 )
{
    add_header Cache-Control no-cache;   # ← 就是它把 HSTS 顶掉的
}

把动态页和静态资源拆成两个 location,各管各的头,问题就没了。

四、加了三个自愈任务

30 3 * * *  宝塔备份只留最近 7 份
15 4 * * *  站点日志 > 200M 自动清空
20 5 * * *  db_data 目录缺 x 位自动补

最后一条是这次的教训——目录权限一旦被改坏,MySQL 连启动都启动不了,与其下次再手动救,不如每天自愈一次。

五、备份

动手前做了双份备份:全库 mysqldump(4.5 MB)和原图打包(416 MB)。数据一条没丢:19 篇文章、8 个页面、7 条说说、37 条评论。

唯一还没解决的是异地备份——现在所有备份都和站点在同一台机器上,磁盘满那类故障里,它们是会一起死的。

总之,欢迎回来 🎉