hot-limter
秒杀限流工具0.01
核心思想是采用双锁来对热点商品进行保护,用户流量需要先抢到基于机器的计数器锁,才能去抢基于redis的购买锁,从而达成限流的目的
主要技术是计数器锁,redis锁和java缓存,
先在机器中设置购买次数作为计数器锁,redis中设置商品数量作为redis锁
然后java第一步检查内存中商品数量确认是否可以抢锁,
第二步抢内存中的计数器锁,获得指定值表明抢到了锁,获取其他值认为抢锁失败,商品售空
第三步使用decr抢redis锁,返回值大于等于0表明抢到了锁,可以执行购买请求。返回值小于0表示没抢到锁,购买失败。
目前的规则是只有2的n次方次请求才能购买商品,所以在请求流量不够大或商品数量过多的情况下会出现明明有库存却无法购买的情况
另一项规则是默认一个人一次只能购买一件商品,不存在买多个的情况
未预设热点的商品会按默认规则,不限流不处理。 后期版本可能会增加自动发现热点商品并限流(可能)
采用redis频道订阅的方式,成功购买商品的服务器负责检查余量,当为0时推送商品售空信息,其他服务器会把商品库存置零。
后期版本可能会更改为推送商品现有库存,但理论上秒杀商品的库存只有售空和未售空两种可能,所以大概率不会改
内部对是否热点的查询使用的hashmap,如果高并发的设置保护商品可能会出问题,但设置保护商品本来也不应该出现高并发的情况
或许当加入自动保护策略时会受影响,但目前没有这种问题
因为售空信息是一次性推送的,所以如果发生退货服务器信息不会自动更新
使用方式为新建HotLimter对象,为对象设置whenNoContain(不是保护商品的查询策略),buyGood(不是保护商品的购买策略),JedisPool(redis连接池,用于数据更新和推送订阅),buySuccess(保护商品购买成功的执行策略)
保护商品的设置为HotLimter的add方,解除为del方法法,保护商品要继承ProtectThing接口
最终前端的查询和购买方法直接调用HotLimter的get和buy即可
在单项目测试中,5件商品,500并发的商品购买请求,触发了27次流量过滤,发送了7次购买请求,卖出5件商品,其余请求均是内存访问
在双项目测试中,5件商品,100并发的两客户端商品购买请求,可能由于机器性能原因,一个客户端卖出5件商品,另一个客户端发送了三次失败的购买尝试
v0.0.2更新内容
将第二步的计数器锁更改为基于内存的AtomicInteger,不再所有机器共享
以及添加了del方法作为热点商品的保护解除