AWS部署Varnish无法突破3.5k req/s,求吞吐量调优方案
首先先确认你的缓存命中率是100%——用varnishstat -1 | grep cache_hit查看,如果命中率不达标,回源S3会严重拖慢整体速度。假设缓存已经完全命中,结合你的配置和场景,这些改动应该能帮你突破当前的吞吐量瓶颈:
1. 优化线程池响应速度
你设置的thread_pool_add_delay=2秒太保守了,当突发高并发请求时,Varnish需要等待2秒才会新增工作线程,大量请求会因此排队。建议把这个值大幅调低:
varnishadm param.set thread_pool_add_delay 0.01
另外,默认的thread_queue_limit=20也偏小,当队列请求超过这个数值时Varnish会直接拒绝新连接,高并发场景下建议调大:
varnishadm param.set thread_queue_limit 100
你当前的thread_pool_min=500和thread_pool_max=5000配置没问题,m4.large的2vCPU足够支撑这个线程规模。
2. 扩容连接队列与系统网络参数
- Varnish默认的
listen_depth=1024在高并发下容易被占满,导致请求被丢弃,建议调大:
varnishadm param.set listen_depth 4096
- 同时需要修改操作系统的网络内核参数(编辑
/etc/sysctl.conf后执行sysctl -p生效),避免系统层面的网络瓶颈:
net.core.somaxconn = 4096 net.ipv4.tcp_max_syn_backlog = 4096 net.core.netdev_max_backlog = 10000 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_fin_timeout = 10
3. 简化VCL配置,减少无效开销
你的VCL里有些操作会额外消耗资源,建议调整:
- 去掉
set req.http.Date = now:这个操作会让每个请求的Date头唯一,不仅完全没必要,还会增加CPU消耗,甚至可能干扰缓存逻辑。 - 去掉
beresp.do_gzip = true:S3会根据请求头自动返回gzip压缩内容,Varnish重复压缩纯属浪费资源,哪怕CPU没瓶颈也会增加响应时间。
修改后的精简VCL:
vcl 4.0; backend default { .host = "******.s3-website-eu-west-1.amazonaws.com"; .port = "80"; } sub vcl_recv { set req.http.Host = "******.s3-website-eu-west-1.amazonaws.com"; unset req.http.Cookie; } sub vcl_deliver { unset resp.http.set-cookie; }
4. 调整超时参数,释放闲置资源
你设置的timeout_linger=100000秒会让空闲连接长期占用资源,导致新请求无法获取可用连接。建议调小到合理值,比如100毫秒:
varnishadm param.set timeout_linger 0.1
idle_send_timeout=0可以保留(允许长连接复用),但配合合理的timeout_linger才能高效利用连接资源。
5. 优化突发请求处理能力
调大rush_exponent参数,提升Varnish应对突发流量的响应速度,默认值3可以调整到10:
varnishadm param.set rush_exponent 10
同时降低thread_pool_timeout,让闲置线程更快释放,默认300秒可以改成60秒:
varnishadm param.set thread_pool_timeout 60
6. 验证测试工具是否存在瓶颈
有时候JMeter集群本身会成为吞吐量上限,建议用更轻量的工具(比如wrk)做对比测试:
wrk -t4 -c1000 -d30s http://your-varnish-ip:6081/your-file-path
如果wrk能测出更高的吞吐量,说明你需要优化JMeter的配置(比如增加线程数、调整连接池参数等)。
每次修改参数后,用varnishstat监控client_req、cache_hit、thread_pool_queue等关键指标,确认改动的实际效果。
内容的提问来源于stack exchange,提问作者Teddy Ferdinand

