最近为了准备一年一度的双十一大促,让我们忙碌于流量预估、服务扩容、压测等各种事项中,其中压测作为其中必不可少的且十分重要环节,让自己纠结在一个问题上,废了一些心思,没错,就是我今天要讲的同步压测和异步化压测。
先说说什么是同步压测什么是异步压测呢?
一、 同步压测和异步压测分析
1、 同步压测方式
常用的方式为多线程的方式,例如:并发10个,那么客户端启动10个压测线程,并且10个连接的请求。如下图:
2、 异步压测方式,
可以理解为是异步IO的压测方式,例如:并发产生10个请求,客户端可以启动5个线程,每个线程异步方式处理2个连接,那么同样可以10个并发的要求。如下图:
3、为什么需要考虑用异步的压测方式
我觉得可以举一个例子更为形象:
假设我们的压测场景为需要模拟一个全链路行为方式压测,如:模拟客户端 第一步登陆 第二步请求接口 第三部退出三种行为,并发压测1.5w qps
这种全链路的压测场景其实对后端的真实服务器,产生的至少是3次的请求。在三台压测服务器下,采用同步的压测方式也就是每台需要开启5000个线程,这样的方式有如下缺陷:
1) 每个线程处理一次全链路请求,容易造成资源的浪费。
2) 但发生在请求等待的情况时,请求处于一个等待的状态,造成实际的压测不符合预期。
那么采用异步的压测方式,将有效的解决这种问题,但我觉得全链路如果适用到前后没有关联的连接请求,全链路的压测方式,就会会产生一些压测并发超出预期的情况
二、 采用异步压测模式遇到的困扰描述
1、 描述
在双十一前,由于压测的服务是单一功能型的后台服务业务,前后请求中没有存在关联的行为,在分别采用异步压测和同步压测从而产生了不同的结果预期;
1)采用abench压测,采用同步的方式,压测后的结果能达到双十一前的压测预期。
2)采用公司的压测平台,使用的异步压测方式。不能满足预期。
2、 分析手段
两种压测方式都是并发启动的1.5w qps,那么结果为什么不一样呢?我们对于两种方式进行如下的处理分析:
- 在前端的FE层开启了nginx的毫秒级日志,目的用于记录每个毫秒接收到丢弃请求。
- 通过对两种场景下产生的nginx的access日志,通过awk提取,聚合发现出采用异步的方式在每毫秒接收到的请求数>6,的会明显很多。
- 为了更加细致的分析,我们提出了一种更为细致的方式,如下:
1) 不应该通过每毫秒进行分析,因为按照php对于请求的原理,是同步请求方式,也就是100个线程,即使我在第一毫秒有99个query过来,只要我在单一周期内,没有请求,这样的每秒聚集方式是符合预期的。
2) 那么应该采用什么样的周期进行分析呢?采用平时正常状态的一个请求接口的平均rt合适,为什么呢?因为一个正常请求rt,表示处理,表示了这个请求在这一层正常处理延时(如果采用,压测状态下的一个请求延时那么,这个时候的平均rt是不准确的,一定会有等待延时)。
3) 那么通过对日志细致分析,我们可以看到采用同步的压测方式单位周期100ms的请求数目更加平稳,得到了如下的结果分析如下:
图一:同步发压,1台服务对于每1ms,统计过去100ms收到的请求数
图二:异步方式发压,1台服务对于每1ms,统计过去x ms(x=40 60 100)收到的请求数
三、 结论
采用异步的方式发压,对于单一接口请求方式,容易出现没秒内,请求集中聚集的情况。也就是说,如果每秒需要发起1.5w qps,实际集中在每秒中的400ms请求完,而剩余的600ms处于等待,从而导致服务端没发在正常的处理周期内远远超过实际能预期的处理能力。