springboot+redis实现秒杀浅析

秒杀在电商业务中是非常典型的需求,有各种方案,下面浅析一下使用redis如何来实现。
场景:有个秒杀系统,大家都来抢100瓶飞天茅台,先到先得。
示例:通过springboot整合redis,利用StringRedisTemplate操作redis的list队列尝试一下。

@Component
public class RedisService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 添加字符串并设置过期时间
     * @param key
     * @param value
     * @param duration
     */
    public void addString(String key, String value, Duration duration) {
        stringRedisTemplate.opsForValue().set(key, value, duration);
    }

    /**
     * 查找字符串
     * @param key
     * @return
     */
    public String findString(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    /**
     * 根据Key删除
     * @param key
     * @return
     */
    public Boolean deleteByKey(String key) {
        return stringRedisTemplate.delete(key);
    }

    /**
     * 在队列尾部减少一个对象
     * @param listName
     * @return
     */
    public String removeOneEntryOnListRight(String listName) {
        return stringRedisTemplate.opsForList().rightPop(listName);
    }

    /**
     * 在队列头部新增对象
     * @param listName
     * @param args
     * @return
     */
    public Long addEntriesOnListLeft(String listName, Collection<String> args) {
        return stringRedisTemplate.opsForList().leftPushAll(listName, args);
    }

}

其中主要是addEntriesOnListLeft和removeOneEntryOnListRight方法。addEntriesOnListLeft方法在队列的头部新增对象,若没有这个队列则会创建该队列,然后将一个集合统统塞到这个队列中。removeOneEntryOnListRight方法会删除队列中最后一个元素,然后返回这个元素的值,若队列中灭有元素了,那么会返回null,且它们都是原子操作。
这样,每个请求都无需经过加锁操作,直接利用redis的单线程特性,即可实现高并发下的秒杀:请求到达redis,redis会逐个执行,每一次执行要么返回一个值,要么返回null,很显然,有返回值的就是抢到了,返回null的就是没抢到。
对应到redis的操作指令为在队列的左侧新增lpush和在队列的右侧消费rpop。
使用方式
先在任务开始时向redis队列中插入一个大队列

		List<String> entriesList = new LinkedList<>();
        for (int i = 0; i < 100; i++){
            entriesList.add("商品" + i);
        }
        redisService.addEntriesOnListLeft("listName",entriesList);

后在秒杀的方法中操作如下

		String redisResult = redisService.removeOneEntryOnListRight("listName");
        if (null == redisResult) {
            //说明没抢到
            System.out.println("没抢到");
        }else{
            //说明抢到了 执行抢到逻辑
            System.out.println("抢到了");
        }

感兴趣的小伙伴可以尝试一下,看看是否满足秒杀场景哦( ̄▽ ̄)"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值