抢红包:Redis+Lua脚本
参考文章:https://blog.csdn.net/hengyunabc/article/details/19433779/
方案介绍
概念:大红包(原始红包)、小红包(拆分后的红包)
1.发红包成功后,预先生成小红包,插入数据库,红包对应的用户ID是null。
2.大红包对应两个redis队列,未消费队列、已消费队列。
3.redis中用一个map,过滤已经抢到红包的用户。
3.抢红包请求发出后,进行业务校验:请求参数校验、解析用户信息、解析红包信息与红包可抢数量
4.利用Lua脚本,执行以下逻辑:根据map,判断当前用户是否已经抢过红包、是否还有剩余可抢红包,如果都通过,从未消费队列中取出一个小红包,push到已消费队列中,后将用户ID放入map中,否则返回相应错误。
5.异步update小红包记录:用一个单线程批量把已消费队列的红包取出,在批量update红包的用户ID到数据库中。
6.返回请求。
Lua脚本
参考文章中的Lua脚本,初步学一下
-- 函数:尝试获得红包,如果成功,则返回json字符串,如果不成功,则返回空
-- 参数:红包队列名, 已消费的队列名,去重的Map名,用户ID
-- 返回值:nil 或者 json字符串,包含用户ID:userId,红包ID:id,红包金额:money
-- 如果用户已抢过红包,则返回nil
if redis.call('hexists', KEYS[3], KEYS[4]) ~= 0 then
return nil
else
-- 先取出一个小红包
local hongBao = redis.call('rpop', KEYS[1]);
if hongBao then
local x = cjson.decode(hongBao);
-- 加入用户ID信息
x['userId'] = KEYS[4];
local re = cjson.encode(x);
-- 把用户ID放到去重的set里
redis.call('hset', KEYS[3], KEYS[4], KEYS[4]);
-- 把红包放到已消费队列里
redis.call('lpush', KEYS[2], re);
return re;
end
end
return nil
分析抢红包测试思路
-
功能测试分析思路
1.从需求上划分:发红包、抢红包、资金流转
2.从测试分析角度划分:页面展示、页面交互、页面逻辑、接口验证、数据层验证、前后台联测、后台功能验证、权限校验、数据初始化、服务兼容测试等
3.根据需求的特性,进行特定场景测试分析:接口并发测试、性能测试等 -
单接口并发:
1.相同用户 同一红包【线程起100个】
2.不同用户 同一红包【线程数<可抢红包数、线程数=可抢红包数、线程数>可抢红包数】校验点:
(1)sql写入数据验证,是否存在异常数据,比如:相同用户抢同一红包两次;红包被抢个数超出设置值等。
(2)红包抢成功后,后续转账数据流是否正确。
严谨起见,做单据唯一的处理,同一单据不可转账两次。
-
性能测试
假设:我们把抢红包看做是有库存的高并发,当抢红包的人数足够多时,对系统性能会造成影响。比如:前端:页面瞬间涌入大量流量,频繁访问页面资源;用户频繁点击抢红包
服务端控制层(网关):用户跳过前端,恶意用接口频繁访问抢红包接口(同一个用户ID)
服务层:经过前端、网关的抢红包请求依然足够多。
数据层:红包数据更新入库。所以,在测试分析时,需要有一些数据储备:
从红包需求角度出发,分析抢红包流量;
从产品本身用户量出发,分析潜在的抢红包流量;
从PV/UV角度出发,分析页面浏览、点击情况。上述数据结论,如果压力相当大,需要考虑各个层面的应对与测试方案:
1.对各层可能出现的问题,根据实际场景流量做综合分析;
2.与开发确认各层面的解决方案;
3.对各个层面的解决方案进行测试。借助性能测试工具jmeter进行测试与分析:见性能测试分析章节
设置场景行为比例、确定并发数、响应时间、TPS、错误率、服务器性能指标等,可以参考性能测试分析模块而定,此处重点分析该方案可能存在的问题点,从而有针对性的测试。