` 前加一段 JS: ```html ``` `functions_mine.php` 里的 `get_post_view()` 简化为只读: ```php function get_post_view($archive) { $cid = $archive->cid; $db = Typecho_Db::get(); Database::createFiledInTable("views",Database::$type_int_10,"contents"); $row = $db->fetchRow($db->select("views")->from("table.contents")->where("cid = ?", $cid)); return $row["views"]; } ``` 这样缓存页面时 PHP 只读一次(被缓存),阅读量增量全走 AJAX 接口,**缓存期间阅读量准确增长**。 ## 其他顺手优化的 既然都改了,顺手把几个明显的问题也一起处理了。 ### PHP-FPM 原来是 `max_children = 50`,`max_spare_servers = 35`,35 个空闲进程常驻,白白吃掉 1.4GB 内存。 ```ini pm.max_children = 30 pm.start_servers = 4 pm.min_spare_servers = 2 pm.max_spare_servers = 12 pm.max_requests = 500 ``` 加了 `pm.max_requests = 500`,每个进程处理 500 次请求后重启,防止内存泄漏。 ### MySQL Buffer Pool 从 128MB 翻倍到 256MB。加了几条复合索引: ```sql ALTER TABLE blog_contents ADD INDEX idx_type_status_created (type, status, created); ALTER TABLE blog_contents ADD INDEX idx_type_status_views (type, status, views); ALTER TABLE blog_metas ADD INDEX idx_type (type); ``` 开了慢查询日志(阈值 2 秒)方便以后排查。 ### OPcache ```ini opcache.memory_consumption=128 opcache.revalidate_freq=60 ``` `revalidate_freq` 原来默认 2 秒,每次请求都 stat 文件看有没有变。改成 60 秒,减少磁盘 IO。发布文章后手动清理 Varnish 缓存就行。 ## 验证效果 先预热缓存,再压测: ```bash # 预热 curl -s -o /dev/null -H "Host: wanghaoyu.com.cn" http://127.0.0.1/ # 看 X-Cache 头 curl -s -I -H "Host: wanghaoyu.com.cn" http://127.0.0.1/ | grep X-Cache # X-Cache: HIT # 压测 300 并发 ab -n 2000 -c 300 -H "Host: wanghaoyu.com.cn" http://127.0.0.1/ ``` ``` Requests per second: 13903.08 [#/sec] Time per request: 21.578 [ms] (mean) Complete requests: 2000 Failed requests: 0 50% 21ms 95% 26ms 99% 34ms ``` 再试试 500 并发: ```bash ab -n 5000 -c 500 -H "Host: wanghaoyu.com.cn" http://127.0.0.1/ ``` ``` Requests per second: 12801.80 [#/sec] Time per request: 39.057 [ms] (mean) 99% 48ms ``` 看 Varnish 缓存命中率: ```bash varnishstat -1 | grep cache ``` ``` MAIN.cache_hit 6999 99.99% MAIN.cache_miss 1 0.01% ``` ## 缓存清理 发布新文章后需要清理缓存,不然访客看到的是旧内容。写了个脚本放到 `/root/`: ```bash # 全部清理 /root/clean_varnish_cache.sh # 清理指定页面 /root/clean_varnish_cache.sh /archives/200.html ``` 也可以等 5 分钟自动过期,看需求取舍。 ## 一点感受 1. **单次 PHP 渲染 215ms 对静态博客来说太奢侈了**。Typecho 首页就 28 次 SQL 查询,MySQL 只要 6ms,剩下 209ms 全花在 PHP 代码和模板上。对于大部分访客来说,看到的内容在缓存期内不会变,没必要每次都跑一遍 PHP。 2. **Varnish 的缓存命中响应是 0.2ms**,比 PHP 快了 1000 倍。这就意味着 Varnish 面对并发时几乎不消耗资源,所有压力都绕过了。 3. **阅读量异步化这个设计值得单独说**。很多缓存方案直接忽略这个问题,但这在博客场景里很影响体验。用 AJAX 接口做穿透处理,VCL 里加一行 `pass` 就搞定了,复杂度不高。 4. **3.6GB 跑 Typecho 博客完全够用**,关键是用对缓存。优化前 PHP-FPM 空闲驻留 35 个进程吃掉 1.4GB,优化后只有 4 个 worker,可用内存从 1.9GB 涨到 2.2GB。 5. **上游有 Nginx 做反代的情况下,加 Varnish 特别简单**。不用处理 TLS,不用改 DNS,Varnish 只监听 80 端口做 HTTP 缓存就行。 --- **相关链接**: - [Varnish Cache 官方文档](https://varnish-cache.org/docs/) - [Typecho 官网](https://typecho.org/) - [Handsome 主题](https://handsome.ihewro.com/)
Loading...
Loading...