Apache2.4 mod_ratelimit限速配置不生效 速度固定121KB/s如何解决
故障成因
你遇到的固定121KB/s问题是两个因素共同导致的:
- 配置语法错误:你贴的规则里把测试备注直接写在了
SetEnv指令行尾,SetEnv rate-limit 100 = 121kb/sec这种写法会让Apache把rate-limit的赋值识别为100 = 121kb/sec这个非数字字符串,而非你预期的数字值。 - 版本bug:Debian 11默认源搭载的Apache 2.4.48版本中,mod_ratelimit存在已知逻辑缺陷:当读取到的
rate-limit值不是纯数字时,不会抛出配置错误,反而会自动fallback到硬编码的1000000B/s(约976Kbps)的限速值,扣除TCP协议开销后实际传输速度就是120-122KB/s,和你的测试结果完全吻合。
你提到的速度从10KB/s缓慢爬升到121KB/s的现象,也完全匹配这个bug触发时的传输表现:模块会先按错误逻辑做流量整形,最终锁定在固定的fallback速率上,和你配置的数字参数没有任何关系。
修复步骤
- 修正配置写法
SetEnv给rate-limit赋值时只保留纯数字,备注单独写在注释行,不要和配置写在同一行,正确示例:
# 限速100KiB/s SetEnv rate-limit 100 # 限速512KiB/s SetEnv rate-limit 512
- 升级Apache修复mod_ratelimit bug
Debian 11官方源的Apache版本不会再推送该bug的修复,需要从bullseye-backports源安装2.4.56及以上版本,执行以下命令:
echo "deb http://deb.debian.org/debian bullseye-backports main" > /etc/apt/sources.list.d/backports.list apt update apt -t bullseye-backports install -y apache2 systemctl restart apache2
- 关闭内核直接发送配置
在需要限速的站点配置(vhost或.htaccess)中添加以下两行,避免Apache调用sendfile/mmap直接把文件交给内核发送,绕过mod_ratelimit的过滤器链导致限速失效:
EnableSendfile Off EnableMMAP Off
- PHP动态分级限速实现
不需要在.htaccess写死规则,直接在PHP业务代码中根据用户等级调用apache_setenv设置对应限速值即可,参考代码:
// 访客:限速400KiB/s if ($user_level === 'guest') { apache_setenv('rate-limit', '400'); } // 一级付费用户:限速1MB/s(即1024KiB/s) elseif ($user_level === 'vip1') { apache_setenv('rate-limit', '1024'); } // 二级付费用户:限速5MB/s(即5120KiB/s) elseif ($user_level === 'vip2') { apache_setenv('rate-limit', '5120'); }
注意传入的第二个参数必须是纯数字字符串,不要带单位或其他字符。
测试注意事项
- 测试时用curl/wget等命令行工具下载,避免浏览器缓存、多线程连接干扰测试结果
- 提前禁用mod_bw、mod_bandwidth等第三方限速模块,避免规则冲突
- mod_ratelimit是单连接限速,如果用户使用多线程下载工具,总速度会随线程数叠加,需要限制单IP总速度的话要额外搭配mod_limitipconn模块使用
内容的提问来源于stack exchange,提问作者Lord Psyan
相关产品推荐
相关产品推荐

