双十一抢券活动接口压测
压测抢券接口能支持最高并发数
https://www-test.****.com/activitys/api/seckill/sessions
https://www-test.****.com/activitys/api/seckill/catchit
1)cookie
2)x-requested-with:XMLHttpRequest
1)/api/seckill/sessions:
无
2)/api/seckill/catchit:
{ "sessionId":"MjAyMDExMDQyMDU1MzUj************" }
1)2个接口的线程的请求头从50000个cookie中按顺序从上往下获取,模拟每个线程都是不同的用户并发;
# 和运维沟通,从测试环境到一份用户名称到本地文件,然后调用生成cookie到接口,批量生成cookie。
def getCookie():
# 当前目录下面的username文件
username_path = 'username_v2.txt'
# 当前目录下面的cookie文件
cookie_path = 'cookie'
# 读取当前目录下面的username文件的username
input = open(username_path, 'r')
lines = input.readlines()
url = "https://graph-test.***.com/authCode/getCookie"
for line in lines:
payload = "{\"userId\":\"\",\"username\":%s}" % line
print(payload)
headers = {
'Content-Type': 'application/json'
}
try:
response = requests.request("POST", url, headers=headers, data=payload)
cookie = response.json().get('result')
output = open(cookie_path, 'a+')
# 获取到的cookie写入到当前目录的cookie文件
output.write('"'+cookie+'"'+'\n')
except Exception as e:
pass
getCookie()
2)/api/seckill/catchit 接口的请求参数sessionId写死成一个全局变量,每个线程都使用同一个sessionId(考虑到sessionId的值不需要是变量,写死对压测不会有影响);
3)清除redis缓存(https://blog.csdn.net/zhoujunjunlove/article/details/114888233),因为数据写入到redis,避免压测redis存在的数据,影响压测结果;
4)通过执行数据库脚本,生成15000个奖品,重置活动开始时间为2分钟后;
DELETE FROM activity_season_result WHERE activity_season_id=15;
UPDATE activity_prize_stats SET `count_has_redeemed`=0 where activity_prize_pool_id in(61);
UPDATE activity_prize SET `count_remain`=15000 WHERE id=158;
UPDATE activity_season SET is_finish=0,begin_datetime=DATE_ADD(NOW(),INTERVAL 2 MINUTE) WHERE `activity_season_id` = 15;
5)等到活动时间开始,执行压测脚本(具体执行步骤:https://blog.csdn.net/zhoujunjunlove/article/details/109187370),压测开始,并发用户数最低并发600个,最高并发1000个,每次并发处理时间60s,逐渐递增并发数100个(考虑到是压测场景是秒抢,奖品抢完了,后面继续压没有什么意义,所以并发时间选择60s);
6)脚本不是一次性从600一直压测到1000,而是,完成并发用户数600个后,手动重复执行3、4步骤,再进行下一次700并发,如此循环:执行3、4步骤——>并发600——>执行3、4步骤——>并发700,。。。并发1000。
1)错误率(2个接口):
并发数在600~800,没有报错并发用户;
并发数在900,1.5%左右并发用户报错;
并发数在1000,0.2%左右并发用户报错
2)响应时间:
1./api/seckill/catchit :
并发数600~800时平均响应时间在190ms左右波动,并发数900~1000平均响应时间在300ms左右波动,
呈现趋势:没有报错的并发数,并发数越高,平均响应时间越长;
2./api/seckill/sessions
并发数600时平均响应时间最低574.21ms,并发数1000时最高响应时间1073.47ms,
呈现趋势:没有报错的并发数,并发数越高,平均响应时间越长;
3)QPS
1./api/seckill/catchit:
并发数700时QPS最高843/sec,随着并发数渐渐递增1000,QPS基本保存在800/sec左右波动;
2./api/seckill/sessions
并发数600~800是QPS最高并发数,QPS在760/sec左右波动,并发数900~1000时QPS在720/sec左右波动;
双11抢券接口测试,提测时,抢券接口的压测结果最高只能支持并发数200,通过压测调优后,抢券接口能达到最高并发数800,接口性能提高了4倍,保证了公司双十一活动正常运行,具体 如下:
1)/api/seckill/catchit:
问题:抢券的接口,一开始只能支持200的并发量,持续尝试优化下,找到接口的性能瓶颈在zk分布锁,接口报错超时,是因为前端发起的请求数超过API能够支持最高的链接数,超过的请求一直等待,就会超时报错;
解决方案:把zk分布式锁从API放到web应用层,让应用层处理并发。
效果:单个接口压测,支持的并发数从200 上升到 1000
2)/api/seckill/sessions
问题 :获取sessionId的接口,并发数在150,就出现大量接口超时报错,查看服务器资源发现,服务器只部署了3个节点,cpu已经跑满了。
解决方案:增加服务器的节点,配置8个节点,每个节点4g
效果:单个接口压测,支持的并发数从 150 上升到 900(性能瓶颈基本可以判断在应用服务器的机器配置,增加机器节点越多,能支持的并发数能更高)
3)单个接口压测通过后,进行2个接口一起压测的结果:
并发数的平均响应时间都低于1000ms、QPS大于700,而并发数大于900出现报错,所以,最高(最佳)的并发数为800
并发用户数(线程数)600
并发用户数(线程数)700
并发用户数(线程数)800
并发用户数(线程数)900
并发用户数(线程数)1000