启用HTTP/2的Apache反向代理请求大量60KB小缩略图时性能下降问题排查求助
你遇到的这个问题确实有点反直觉——按道理HTTP/2的多路复用就是为了解决大量小文件并发请求的场景,但实际切换后反而变慢了,尤其是批量请求200个左右60KB缩略图的时候。结合你的描述(后端仅支持HTTP/1.1、文件已预缓存到磁盘),我给你梳理几个排查方向,你可以逐一测试看看:
检查Apache HTTP/2的并发流与窗口配置
HTTP/2标准默认限制每个连接最多100个并发流,Apache也有对应的配置项可能会限制这个数值。如果你的200个请求超出了配置的并发流上限,就会出现排队等待的情况,反而不如HTTP/1.1的多连接并行高效。另外,HTTP/2的流量控制窗口大小如果设置过小,也会导致小文件传输断断续续拖慢总耗时。你可以检查并调整H2MaxSessionStreams、H2StreamWindowSize、H2InitialWindowSize这些配置参数,适当调大后测试性能变化。排查反向代理到后端的连接复用情况
因为后端只支持HTTP/1.1,Apache作为HTTP/2反向代理需要把前端的多路复用请求转换成HTTP/1.1请求发给后端。这时候后端连接池的配置就至关重要——如果Apache给后端开的HTTP/1.1连接数太少,200个并发请求就会排队等待空闲连接,直接拖慢整体速度。你可以调整ProxyPass的连接池参数,比如设置ProxyPass / http://backend/ connectiontimeout=5 timeout=30 keepalive=On max=100,确保后端连接池足够容纳并发请求,并且开启长连接复用。验证磁盘IO是否真的无瓶颈
虽然你说缩略图已经预缓存到磁盘,但批量200个请求同时读取时,还是可能触发磁盘IO瓶颈——比如机械硬盘的随机读取性能有限,或者操作系统的文件缓存没有真正把所有缩略图加载到内存里。你可以在请求高峰期用iostat、vmstat这类工具查看磁盘的IO使用率、等待时间,如果%util接近100%或者await数值很高,那磁盘IO就是问题所在。这时候可以考虑用Apache的mod_cache配置内存缓存区,或者把缩略图存储换成SSD。深挖Chromium瀑布图的细节差异
你提到HTTP/2的请求不再stall,但总时间更长,建议仔细对比两张瀑布图里每个请求的阶段耗时:比如排队时间(Queueing)、后端响应等待时间(Waiting (TTFB))、内容传输时间(Content Download)。如果是TTFB变长,说明代理转发或后端处理的延迟增加;如果是Content Download阶段变长,大概率是HTTP/2的流量控制窗口设置不合理。找到差异最大的阶段,就能精准定位问题点。检查Apache的MPM模式与进程/线程配置
如果Apache用的是prefork模式,处理HTTP/2请求的性能会非常差——因为prefork是单进程单连接的模式,完全发挥不了HTTP/2多路复用的优势。你可以用apache2ctl -l(或httpd -l)查看当前MPM模式,要是prefork的话,建议切换到event模式,同时调整StartServers、MaxRequestWorkers等参数,确保有足够的线程来处理并发请求。测试是否是客户端HTTP/2实现的问题
有时候浏览器的HTTP/2实现可能存在兼容性问题,你可以换Firefox、Edge等其他浏览器测试,或者用curl命令行批量请求测试:写个简单脚本循环执行curl -v --http2 -o /dev/null https://your-domain/thumbnail-xxx.jpg,对比HTTP/2和HTTP/1.1的总耗时,看是否只有Chromium出现这个问题,还是所有客户端都有性能下降。检查是否启用了不必要的HTTP/2特性
比如如果开启了HTTP/2服务器推送(Server Push),但推送的资源不对或者推送量过大,反而会占用带宽和连接资源,导致真正需要的缩略图请求变慢。你可以暂时注释掉H2Push On配置,关闭推送后测试性能是否有改善。
备注:内容来源于stack exchange,提问作者xhighway999

