对于应用压测大家应该都有一些自己的方式,通常都是构造一些请求,不过构造请求学问就大了。
构造什么样的请求?构造的请求是否真实?构造的请求各种业务场景的配比?读写比例?
对于一个Web浏览型应用来说,相比对纯DB的压测,会更复杂一些,主要因为涉及缓存。
之前采用过很多压测方式,包括ab、httpload等等,这些压测方式的缺点在于无法真实反映一个浏览型系统的性能指标。和其它对DB的查询或是调用外部服务的应用不同,浏览型系统在大量采用Cache和存在命中率的前提下,命中Cache和不命中的性能差距非常大。
如果按悲观的角度,从完全不命中的角度考虑,那么单机的能力会很低,相应的需要增加非常多的机器,而如果把命中率估得很高,又显得太乐观。还有另外一个比较头疼的问题是,即使你知道自己的命中率是多少,你也无法仅仅按百分比去计算你的QPS能力,因为有可能你的命中以外还有额外的开销,并不是内存直接返回的,例如各种ESI。你还需要准确地计算出这些消耗的类型以及它们各自的占比、耗时,最后会被围困在一个存在各种不确定性因素的牢笼中。
最悲催的情况就是你用一个URL去压测,压出来一个非常好的性能,然后上线时发现单机根本达不到这个性能指标,只能临时去加机器缓解。
于是我就在思考,如何摆脱之前那些不确定性因素,我们不去猜测命中率、QPS这些指标,能否通过更真实的线上请求来做?
事实是当然可以,我们随机选取一些机器,通过tcp包拷贝的方式直接将真实请求转发到一台机器处理,做到了真实场景下的压测。
这种压测的效果还是不错的,没再压出不靠谱的那么虚高的指标,回归大地,回归真实。
事实上当我们把单机QPS压到之前出问题的量级时,确实复现了当时的情况,这也进一步证实了这种压测方式是靠谱、真实的。
需要注意的是你需要注意自己的Cache范围,本机Cache还好,如果是分布式Cache,所有机器共享的,那么需要保证被压测机器访问的Cache和其它机器要分开,否则被压机器的Cache永远是命中的。