[性能优化系列] 03. 文件缓存

前文介绍了通过gzip减少流量传输,通过设置Cache-Control减少静态资源的请求,本文继续探讨,如何通过缓存的方式,减少对数据库的压力,从而提升页面响应时间。

## 动态页面性能损耗分析

以Typecho为例(大部分的cms类站点都是类似的架构),用户的http请求,从`index.php`进入web服务,然后PHP代码加载各种组件,接着路由到具体的action或者controller,并在controller中加载model,查询数据库,组装页面,最后渲染模板并输出给浏览器。

![request_flow.png][1]

但是,对于大多数页面或者post,作者完成创作之后,绝大部分时间都不会再改变的了,但每次请求这个文章(举例,譬如:https://www.typechodev.com/servers/aliyun_coupons.html)的时候,都需要走一次所有流程,并从数据库查询文章内容,明显是不合适的。因此,我们可以在整个网站的入口处做优化,将文章内容缓存起来,下次请求过来时,如果发现有缓存,则直接返回缓存内容,从而减少对后端数据库等的压力,从而提升响应时间和网站并发处理能力。

## 动手实现自己的缓存逻辑

####首先我们测试一下启用文件缓存前的接口性能

网上有很多已经做好的文件缓存插件,同学们可以自己去找找。笔者没有用过这类插件,所以没办法给什么建议。不过这种页面缓存技术非常简单,我们也可以自己简单实现一下。

首先我们看一下typecho的入口文件:

begin();

/** 开始路由分发 */
Typecho_Router::dispatch();

/** 注册一个结束插件 */
Typecho_Plugin::factory(‘index.php’)->end();
这个时候,使用`ab -n 1000 -c 100 “https://www.typechodev.com/theme/56.html”`命令进行测试,测试结果:

Concurrency Level: 100
Time taken for tests: 27.302 seconds
Complete requests: 1000
Failed requests: 994
(Connect: 0, Receive: 0, Length: 994, Exceptions: 0)
Total transferred: 28776775 bytes
HTML transferred: 28576775 bytes
Requests per second: 36.63 [#/sec] (mean)
Time per request: 2730.203 [ms] (mean)
Time per request: 27.302 [ms] (mean, across all concurrent requests)
Transfer rate: 1029.31 [Kbytes/sec] received
####接着我们修改index.php逻辑,增加文件缓存机制

修改后的`index.php`:

begin();

/** 开始路由分发 */
Typecho_Router::dispatch();

/** 注册一个结束插件 */
Typecho_Plugin::factory(‘index.php’)->end();

$content = ob_get_contents();
ob_end_clean();
file_put_contents($tmp_file, $content);
echo $content;
我们再通过diff看看两者的差异,更清楚看到改动的内容:

![index_diff.png][2]

可见,改动的地方非常少,总括来说就是:

1. 页面开始的地方判断是否有缓存文件,有则直接输出
2. 页面最后将内容缓存起来,以供下次请求使用

同样使用`ab -n 1000 -c 100 “https://www.typechodev.com/theme/56.html”`命令进行测试,结果如下:

Concurrency Level: 100
Time taken for tests: 2.658 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 28786000 bytes
HTML transferred: 28640000 bytes
Requests per second: 376.22 [#/sec] (mean)
Time per request: 265.803 [ms] (mean)
Time per request: 2.658 [ms] (mean, across all concurrent requests)
Transfer rate: 10575.99 [Kbytes/sec] received
缓存前后对比,接口成功率大幅上升(缓存前成功率不到10%,缓存后成功100%),请求平均耗时大幅降低(缓存前平均耗时2730ms,缓存后平均耗时265ms,不到1/10)。

#### 小结

通过上述这种简单的方式,可以10倍提升网站的处理能力。同学们可以自动动手试试。代码能力强的同学,甚至可以加各种缓存策略,进一步优化缓存效果,这个就看自己需求了。

[1]: https://www.typechodev.com/usr/uploads/2017/12/4143749164.png
[2]: https://www.typechodev.com/usr/uploads/2017/12/3119693559.png

上一篇 2017-11-30 上午9:24
下一篇 2017-12-20 上午7:01