Apache作为反向代理部署在业务入口时,除了完成请求转发和负载均衡,还可以通过代理缓存直接把已经获取过的响应返回给客户端,从而显著减少源站请求数量和公网出站流量。但如果链路整体带宽比较紧张,即便缓存命中率很高,一个下载大文件的客户端仍然可能把剩余带宽全部占满,导致其他用户的网页、SSH会话或API调用出现明显延迟。Linux内核自带的CAKE队列规则正好可以解决这个问题,它能够在出站方向对不同的网络流进行公平调度,并实施主动队列管理。把Apache代理缓存与CAKE带宽管理放在一起使用,可以先用缓存降低需要发送的总数据量,再用CAKE保证剩余流量被合理分配。

一、Apache代理缓存的核心配置与命中策略
Apache的代理缓存能力主要来自mod_proxy、mod_cache以及具体存储模块mod_cache_disk或mod_cache_socache。其中mod_proxy负责把请求转发到后端服务器,mod_cache提供HTTP缓存逻辑,mod_cache_disk将缓存内容写入磁盘,mod_cache_socache则可以把小型对象放在共享内存中提高访问速度。为了让缓存在反向代理场景下正常工作,至少需要加载这些模块,并声明缓存存储目录。
一个典型的Apache虚拟主机缓存配置如下所示,启用缓存后,Apache会优先检查本地是否已经有可用的响应副本。如果缓存命中并且仍然新鲜,就直接从本地返回,不再向后端源站发起请求。这样不仅降低了后端压力,也减少了代理节点向外转发请求时产生的上行流量。需要注意的是,CacheEnable disk表示对指定URL路径启用磁盘缓存,CacheRoot定义了缓存文件存放位置,而CacheDefaultExpire则用于给缺少明确过期时间的资源设置默认有效期。
<IfModule mod_cache.c>
CacheRoot /var/cache/apache2/mod_cache_disk
CacheEnable disk /
CacheDirLevels 1
CacheDirLength 2
CacheDefaultExpire 3600
CacheMaxExpire 86400
CacheIgnoreHeaders Set-Cookie
</IfModule>
<VirtualHost *:80>
ServerName proxy.ippipp.com
ProxyPreserveHost On
ProxyPass / http://192.168.10.20:8080/
ProxyPassReverse / http://192.168.10.20:8080/
CacheEnable disk /
CacheRoot /var/cache/apache2/mod_cache_disk
CacheDirLevels 1
CacheDirLength 2
CacheDefaultExpire 3600
CacheMaxExpire 86400
</VirtualHost>
上述配置中,192.168.10.20是后端源站的内网地址,实际部署时需要替换成真实的源站IP或域名。如果后端响应中包含Set-Cookie头,通常不建议缓存,因为不同用户可能看到不同内容。通过CacheIgnoreHeaders Set-Cookie可以让Apache忽略该响应头对缓存判断的干扰,但更安全的方式是由应用层明确设置Cache-Control头,只允许缓存公共内容。
代理缓存的另一个关键点是命中后的带宽收益。假设源站主要提供图片、CSS、JavaScript以及少量HTML,这些静态资源体积较大且变化频率低,非常适合被缓存。当Apache直接从本地磁盘返回这些对象时,代理节点到客户端仍然会消耗一定的公网出站带宽,但代理节点到源站之间的链路完全不会产生流量。如果同时有大量用户访问相同资源,缓存命中率越高,源站方向节省的带宽就越明显。这是后续使用CAKE进行出站整形的基础,因为缓存已经把一部分流量挡在了更靠近客户端的位置。
二、CAKE队列规则的工作机制与tc配置方法
CAKE的全称是Common Applications Kept Enhanced,它是Linux内核中一种较新的排队规则,设计目标是尽量降低网络延迟、公平分配带宽,并抵抗缓冲膨胀问题。与传统的htb或fq_codel相比,CAKE把整形、公平队列、主动队列管理和数据包调度整合在一个qdisc中。它能够自动将流量区分为不同的流,例如根据五元组区分TCP连接或UDP会话,然后对每条流独立排队,保证单条大流量连接不会一直抢占其他小流量连接。
CAKE最常用的配置场景是在WAN出口或服务器出站网卡上设置一个速率上限。它提供了bandwidth参数用来指定链路速率,还可以通过diffserv4、nat、ack-filter等选项进一步优化。对于一台运行Apache反向代理的Linux服务器,可以在出站网卡上配置一个CAKE队列,把总带宽设置成比物理链路略低一些的数值,从而让队列在服务器内部提前吸收突发流量,避免数据在运营商设备上堆积。
以下命令将eth0网卡的根队列替换为CAKE,并将出站速率限制为100Mbit/s。配置完成后,该网卡发出的所有数据包都会进入CAKE调度流程,由内核根据流信息进行公平排队和主动丢包管理。
tc qdisc del dev eth0 root 2>/dev/null tc qdisc add dev eth0 root cake bandwidth 100mbit diffserv4 tc -s qdisc show dev eth0
如果服务器通过PPPoE拨号上网,实际可用带宽会受到PPP封装开销影响,此时可以通过overhead参数修正。例如一条标称100Mbit/s的PPPoE链路,可以设置overhead 44来让CAKE把封装字节计入速率计算,避免整形后的实际吞吐明显低于预期。对于普通的以太网专线或云服务器虚拟网卡,通常可以省略overhead参数,只设置bandwidth即可。
CAKE的公平性来自其对流的隔离。假设一个客户端正在通过Apache下载一个大型ISO镜像,而另一个客户端在访问普通的HTML页面,CAKE会为这两条流分别维护队列。大下载流虽然持续有数据待发送,但小网页流不会被完全饿死,因为CAKE会以轮询或加权方式调度不同流,并优先放行交互类小包。这种效果在带宽接近满载时尤为明显,它能避免单个TCP连接把缓冲区全部填满,从而大幅降低网络的整体延迟。
三、代理缓存与CAKE协同的部署思路
把Apache代理缓存和CAKE放在同一台服务器上时,两者的分工非常清晰。Apache负责内容缓存和响应生成,CAKE负责所有出站流量的排队和整形。当请求命中缓存时,Apache直接从本地存储读取响应体并发送给客户端,此时数据包从服务器网卡出去前会先经过CAKE队列。CAKE不关心这些数据来自缓存还是来自后端实时转发,它只根据数据包所属的流进行调度。命中缓存减少了后端链路的流量消耗,而CAKE则保护了代理节点到客户端这一段的可用带宽。
为了让缓存发挥更大作用,可以在Apache中重点缓存静态资源目录。例如通过CacheEnable disk /static/只对静态路径启用缓存,避免缓存包含用户隐私数据的动态接口。同时设置较长的CacheMaxExpire,并配合Cache-Control: public, max-age=86400响应头,让代理节点和客户端浏览器都能缓存更长时间。这相当于把更多请求消化在代理层,使真正需要经过CAKE塑形的流量进一步减少。
<IfModule mod_cache.c>
CacheRoot /var/cache/apache2/mod_cache_disk
CacheEnable disk /static/
CacheEnable disk /assets/
CacheDirLevels 1
CacheDirLength 2
CacheDefaultExpire 7200
CacheMaxExpire 172800
CacheIgnoreNoLastMod On
</IfModule>
在CAKE侧,可以结合Apache缓存的命中日志来观察实际出站流量构成。如果发现未命中请求消耗了大量带宽,说明缓存策略需要调整;如果带宽仍然被少量长连接占满,则说明CAKE的速率上限可能设置得过高。通常建议将CAKE的bandwidth设置为物理链路速率的85%到95%,例如100Mbit/s链路设置90Mbit/s左右。这样可以保留一定余量给ACK包和突发流量,同时让队列管理更早介入。
对于同时提供HTTPS服务的场景,Apache代理缓存需要谨慎处理加密内容。默认情况下,Apache只能缓存明文响应,因此反向代理通常终结TLS,将解密后的HTTP请求转发到后端,并在返回客户端时重新加密。这种情况下,CAKE会在加密后的数据包离开网卡时发挥作用,而Apache缓存则作用于解密后的明文内容。缓存命中时,服务器只负责本地读取和重新加密,不会占用后端连接资源。
四、监控调优与常见问题排查
判断Apache代理缓存是否有效,主要看缓存命中率。可以通过mod_cache的诊断日志或自定义响应头来获取命中信息。例如在Apache配置中添加CacheDetailHeader on,响应中会出现X-Cache-Detail头,显示本次请求是命中缓存还是发生了未命中。也可以分析访问日志,看哪些URL频繁返回200但没有到达后端。命中率越高,说明代理缓存对带宽的削减作用越大。
<IfModule mod_cache.c>
CacheDetailHeader on
CacheHeader on
CacheRoot /var/cache/apache2/mod_cache_disk
CacheEnable disk /
</IfModule>
CAKE的运行状态可以通过tc -s qdisc show dev eth0查看。输出中会包含已发送字节数、丢包数、队列长度以及主动丢弃统计。如果drops数值持续增长,说明带宽已经达到限制,CAKE正在通过丢弃或标记数据包来控制队列深度。此时可以考虑提高带宽参数,或者优化Apache缓存以减少出站流量。如果backlog长期不为零且延迟上升,则说明队列持续积压,可能需要降低CAKE带宽上限,让整形更早发生。
另一个常见问题是缓存文件占用过多磁盘空间。Apache的磁盘缓存会随着时间增长不断写入新对象,如果不定期清理,可能耗尽磁盘。可以通过htcacheclean工具维护缓存目录,例如通过cron周期运行htcacheclean -d30 -n -t -p/var/cache/apache2/mod_cache_disk -l512M,限制缓存总量为512MB。这个工具与CAKE没有直接关系,但它能保证Apache缓存长期稳定运行,避免因磁盘写满导致响应变慢或缓存失效。
最终部署时建议先用tc qdisc add dev eth0 root cake bandwidth 90mbit在测试环境验证CAKE行为,再逐步调整Apache缓存范围。观察高峰时段的RTT和丢包情况,确认小流量交互类请求没有受到大下载任务影响。通过这种组合方式,一台普通的Linux服务器就能完成从前端缓存到出口流量整形的完整带宽管理,无需依赖昂贵的商业流量控制设备。
Apache代理缓存CAKE带宽管理流量整形修改时间:2026-08-21 10:33:26