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 args) {
        return stringRedisTemplate.opsForList().leftPushAll(listName, args);
    }

}

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

		List 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("抢到了");
        }

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

你可能感兴趣的:(redis,redis,spring,boot,java)