Apache缓存过滤及其原理

apche 提供了cache的功能,能够将应用服务端的资源缓存在apache中, 尤其是在apache是代理服务器,原始服务器的物理距离非常远的时候, 性能就能够非常好的体现。

所以此时的网关服务器也可以作为缓存服务器使用。 因为公司使用的是apache2.0系列的。 所以在它那里发现它只支持URL的strcasecmp匹配。 所以匹配所有的URL为 ‘/‘。但是我们希望提供普遍的过滤功能。 只缓存 .jpg,.png,.css 等不变的内容。而将经常需要改成的 .html , .js 不缓存。

所以我们的方案是在 cacheenable 中增加一个可变参数,正则配置的参数。 当正则匹配存在的时候,只使用正则批准,如果不存在,则使用原来的 url的匹配。保证与原2.0的兼容性。

网关cache原理

  • 不存在缓存的时候,客户端发送请求给网关,网关再向后端发送请求,然后返回给网关,网关返回给客户端。
  • 存在缓存的时候,首先,mod_cache将是一个URL映射模块,也就是说,如果一个URL已经被缓存并且这个缓存尚未失效,该请求将由mod_cache直接处理。这也意味着在处理一个请求时通常还要发生的其他阶段:比如权限验证,mod_proxy或mod_rewrite处理的阶段,将不会发生。网关可以直接返回内容给客户端。

cache 类型

mem

基于mem缓存,在高级设置中已经实现,填入mem会产生配置如下

CacheEnable mem 
MCacheSize 4096
MCacheMaxObjectCount 4
MCacheMinObjectSize 1
MCacheMaxObjectSize 1048576

disk

基于disk缓存,需要另外填写配置文件

CacheDefaultExpire 3600

CacheEnable disk /
CacheRoot /tmp/apacheCache
CacheDirLevels 3   
CacheDirLength 4
CacheMaxFileSize 1048576
CacheMinFileSize 10

ramdisk实现方案

基于disk缓存,将CacheRoot设置为内存盘目录,开机的时候自动建立整个内存的10%用于存放缓存。 ​

缓存文件

在CacheRoot的目录下,生成带后缀的缓存文件.data 和 .header。 可以使用strings命令查看文件 .data保存了缓存文件内容 .header保存了缓存文件的头信息。

自动测试

  1. 使用curl发送请求
  2. 从请求中解析url,从url中获取服务路径号和url的路径
  3. 从服务路径中获取对应服务的缓存header文件,使用 strings 解析,使用grep搜索url的路径来判断url是否在缓存中。

性能测试

大文件性能测试

 ab -n 100 -c 100 https://192.168.41.92:451/icons/123.png

Server Hostname:        192.168.41.92
SSL/TLS Protocol:       TLSv1/SSLv3,AES128-SHA,1024,128
Document Path:          /icons/123.png
Document Length:        8675067 bytes (8.27M)
Concurrency Level:      100
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      867547978 bytes
HTML transferred:       867506700 bytes

Server Software:        Apache/2.4.7
Time taken for tests:   16.630 seconds
Requests per second:    6.01 [#/sec] (mean)
Time per request:       16630.198 [ms] (mean)
Time per request:       166.302 [ms] (mean, across all concurrent requests)
Transfer rate:          50943.94 [Kbytes/sec] received
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       29 3853 1878.0   4418    6428
Processing:  1629 7901 3349.7   9461   11308
Waiting:       13  992 1020.1    505    3371
Total:       1658 11754 5163.3  13795   16620

Server Software:        SSL/5.x.x
Time taken for tests:   11.467 seconds
Requests per second:    8.72 [#/sec] (mean)
Time per request:       11467.149 [ms] (mean)
Time per request:       114.671 [ms] (mean, across all concurrent requests)
Transfer rate:          73881.91 [Kbytes/sec] received
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        4 4435 3071.4   5345    8180
Processing:   293 1948 1288.8   1616    4072
Waiting:        0   18  18.2     11      87
Total:        300 6383 4301.5   6982   11466

小文件性能测试

 ab -n 1500 -c 1500 https://192.168.41.92:452/

Server Hostname:        192.168.41.92
Server Port:            452
SSL/TLS Protocol:       TLSv1/SSLv3,AES128-SHA,1024,128
Document Path:          /
Document Length:        12166 bytes
Concurrency Level:      1500
Complete requests:      1500
Failed requests:        0
Write errors:           0
Total transferred:      18788981 bytes
HTML transferred:       18249000 bytes

Server Software:        Apache/2.4.7
Time taken for tests:   3.901 seconds
Requests per second:    384.50 [#/sec] (mean)
Time per request:       3901.171 [ms] (mean)
Time per request:       2.601 [ms] (mean, across all concurrent requests)
Transfer rate:          4703.36 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       84  367 412.0    314    3504
Processing:     5   23  10.9     21     111
Waiting:        4   21  10.4     18     101
Total:        103  391 414.1    336    3544

Server Software:        SSL/5.x.x
Time taken for tests:   3.234 seconds
Requests per second:    463.88 [#/sec] (mean)
Time per request:       3233.575 [ms] (mean)
Time per request:       2.156 [ms] (mean, across all concurrent requests)
Transfer rate:          5707.93 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       83  261  31.1    267     340
Processing:     1   14   7.3     13      55
Waiting:        0   12   7.0     11      53
Total:         90  275  31.5    281     344

测试分析

  1. 使用cache的时候性能比没有使用时提高20%-30%性能。
  2. 文件越多,性能越高。
  3. 因为ab测试时是单文件测试,但是真实情况下多请求的时候性能是叠加的。

缓存满时的行为

缓存文件大于内存盘的空间时的报错: >error.log:10172:[Wed Jul 20 11:20:29 2016] [error] cache_disk: Error when writing cache file for URL 192.168.41.92/icons/123.png?

手动过期

直接删除CacheRoot目录下生成的缓存文件

清理磁盘缓冲区

htcacheclean 可以用于将mod_disk_cache的磁盘缓冲区占用的空间保持在一个合理的水平。 在SSL5.2.4中没用编译这个工具,需要增加

2.4的mod_cache

配置过滤 url 指令

    CacheQuickHandler off
    <LocationMatch  ".*(jpg|gif)">
        CacheEnable disk
    </LocationMatch>

    CacheRoot /tmp/apacheCache
    CacheDirLevels 3
    CacheDirLength 4
    CacheMaxFileSize 1048576
    CacheMinFileSize 10
  1. 在LocationMatch 的容器中加入 CacheEnable 的指令,将2.0作用域是RSRC_CONF变为RSRC_CONF|OR_AUTHCFG。
  2. CacheQuickHandler off 将快速处理的挂钩关闭, 将处理阶段延后到handler业务处理阶段
    这个指令将原来的 ap_run_quick_handler 转到 ap_run_handler 阶段,
    因为 ap_location_walk 阶段在 ap_run_quick_handler 阶段之后,对url的处理也是在ap_run_quick_handler 之后的。

过滤器的处理

apache 2.0 mod_cache 实现url过滤功能

原mod_cache配置

CacheEnable disk /

其中 / 表示 url-string,在代码中这个url-string只在ap_cache_get_providers的函数中对providers进行了判断,

if ((ent[i].url) && !strncasecmp(url, ent[i].url, ent[i].urllen))

其中 url 表示 r->parsed_uri.path, ent[i].url 表示 url-string。
通过这个判断来选择providers。

实现url过滤

所有如果需要在 apache 2.0 mod_cache 实现url过滤功能,只需要改造这个条件语句,将这个条件变成正则表达式的判断。
在 apache2.0 提供了 c 接口啊正则表达式接口。也可以使用 httpd.h 中的ap_pregcomp等接口实现。
配置变成

	CacheEnable disk .*(jpg|gif)
	CacheDefaultExpire 3600
	CacheRoot /kssl/HRP/cfg/5/cache/ramdisk
	CacheDirLevels 3   
	CacheDirLength 4
	CacheMaxFileSize 10485760000
	CacheMinFileSize 10

不需要使用Location的容器
“.*(jpg|gif)“正则匹配 gif和jpg的图片。

浏览器对cache的返回码

缓存文件不超时的时候,无论是刷新还是强制刷新页面, 缓存文件不被修改。(直接使用缓存文件,没有走到后面的更新缓存的钩子) 缓存文件超时之后,刷新IE浏览器的页面,页面返回 304 的返回码,缓存文件不更新 强制刷新之后,页面返回 200 的返回码,缓存文件更新。

CacheDefaultExpire

指令指定缓存文档的默认时间(以秒为单位),如果文档中没有提供过期日期和上次修改日期。 由CacheMaxExpire指令指定的值不会覆盖此设置。

CacheMaxExpire

指令指定在不检查源服务器的情况下保留可缓存HTTP文档的最大秒数。因此,文档将最多过期这个秒数。即使文档提供了到期日,也会强制执行此最大值。

参考

缓冲指南