LOADING

加载过慢请开启缓存 浏览器默认开启

Redis在项目里的应用

2023/8/14 Redis

'image-20221202170101763'

public Shop huancunjichuan(Long id) {//基于互斥锁实现Redis的缓存击穿
    //从redis查询
    String key = CACHE_SHOP_KEY + id;

    String shop = stringRedisTemplate.opsForValue().get(key);

    //判断是否存在
    if (StrUtil.isNotBlank(shop)) {
        //命中返回
        Shop shop1 = JSONUtil.toBean(shop, Shop.class);
        return shop1;
    }
    if (shop != null) {
        return null;
    }
    String lockkey = null;
    Shop byId = null;
    try {
        lockkey = LOCK_SHOP_KEY + id;
        Boolean istguo = tryLock(lockkey);
        if (!istguo) {
            Thread.sleep(50);
            return huancunjichuan(id);
        }
        String shop2 = stringRedisTemplate.opsForValue().get(key);

        if (shop2 != null) {
            return JSONUtil.toBean(shop2, Shop.class);
        }

        //未命中查数据库 
        byId = getById(id);

        if (byId == null) {
            //不存在返回404
            stringRedisTemplate.opsForValue().set(key, "", CACHE_NULL_TTL, TimeUnit.MINUTES);//把空值存入redis
            return null;
        }

        //存在写入redis
        stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(byId), CACHE_SHOP_TTL, TimeUnit.MINUTES);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    } finally {
        //释放锁
        unLock(lockkey);
    }
    return byId;
}

'image-20221202194325716'

缓存穿透

'image-20221202194417701'

雪崩

'image-20221202194509613'

击穿

'image-20221202194639253'

'image-20221202194751056'

全局ID

'image-20221203184831322'

订单秒杀

@Service
public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {

    @Resource
    ISeckillVoucherService ISeckillVoucherService;

    @Resource
    RedisIDWorker RedisIDWorker;

    @Override
    @Transactional
    public Result seckillVoucher(Long voucherId) {

        SeckillVoucher Voucher = ISeckillVoucherService.getById(voucherId);

        if (Voucher.getBeginTime().isAfter(LocalDateTime.now())) {
            return Result.fail("别急还没开始呢!");
        }
        if (Voucher.getEndTime().isBefore(LocalDateTime.now())) {
            return Result.fail("时间已经过了!");
        }
        if ((Voucher.getStock() < 1)) {
            return Result.fail("库存不足!");
        }
        Long id = UserHolder.getUser().getId();
        synchronized (id.toString().intern()) {
            IVoucherService proxy = (IVoucherService) AopContext.currentProxy();//获取spring代理的类来保证事务的可用
            return proxy.createVoucherorder(voucherId);
            /**
            *要在pom.xml里引入
            * <dependency>
            *	<groupId>org.aspectj</groupId>
            *	<artifactId>aspectjweaver</artifactId>
            *</dependency>
            *否则获取不到
            */
        }
    }

    @Transactional
    public Result createVoucherorder(Long voucherId) {
        Long id = UserHolder.getUser().getId();
            Integer count = query().eq("user_id", id).eq("voucher_id", voucherId).count();

            if (count > 0) {
                return Result.fail("用户已经卖过一次了");
            }
            boolean voucherjieguo = ISeckillVoucherService.update().setSql("stock = stock - 1")
                    .eq("voucher_id", voucherId)
                    .gt("stock", 0)
                    .update();
            if (!voucherjieguo) {
                return Result.fail("库存不足!");
            }
            VoucherOrder voucherOrder = new VoucherOrder();
            Long orderid = RedisIDWorker.nextID("Order");

            voucherOrder.setId(orderid);
            //从线程储存获取用户信息
            voucherOrder.setUserId(id);
            voucherOrder.setVoucherId(voucherId);
            save(voucherOrder);
            return Result.ok(orderid);
    }


}

'image-20221212155609276'加载lua脚本

lua脚本

---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by song.
--- DateTime: 2022/12/12 15:03
---
--订单id
local voucherId =ARGV[1]

local userId =ARGV[2]
--用户id

--库存key
local stockKey = "seckill:stock:"..voucherId
--订单key
local orderKey ="Iseckill:order:"..voucherId
--判断储存是否充足
if(tonumber(redis.call('get',stockKey))<=0) then
    --库存不足返回1
    return 1
end
--判断是否存在重复下单
if (redis.call("sismember",orderKey,userId)==1) then
    return 2--存在重复下单返回2
end
--减库存
redis.call('incrby',stockKey,-1)

redis.call('sadd',orderKey,userId)
return 0

'image-20221212195556570'

@PostConstruct启动项目就加载