一、elastic-job
1.静态任务(略)
2.动态任务:获得定时的逻辑
public static final String CRON_DATE_FORMAT = "ss mm HH dd MM ? yyyy";
public static String getCron(final Date date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(CRON_DATE_FORMAT);
return simpleDateFormat.format(date);
}
二、热点数据隔离
1.流程:
(1)找出热点数据(略)
(2)把热点数据进行隔离处理---存在redis中
(3)用户在下单时,先在redis中查一下是否是热点商品,不是热点商品直接走数据库系统下单,如果是热点商品走kafka排队下单
2.reidsTemplate.boundHashOps
3.控制数据的原子性,因此不能在内存中进行操作,需要用SQL语句在数据库中执行。
4.使用redis定时
redisTemplate.expire(key,timeout,timeunit);
redisTemplate.expire(userKey, 1, TimeUnit.MINUTES);
// userkey 过期时间为 1 分钟
秒杀的思路:
1.判断该商品用户是否在24小时内购买过(通过存入redis的数据进行查询)
2.如果购买了,直接提示用户24小时内无法购买(redis定时设置如上)
3.如果用户没有购买过该商品,则判断该商品是否属于热点商品(查redis中的数据)
4.如果是非热点商品,则走非热点商品抢单流程
/*
1.先递减库存
2.库存递减成功后,执行下单
3.下单失败,需要实现分布式事务
4.下单成功后,要记录用户抢单信息,在24小时内不允许再抢该商品
5.抢单中,有可能存在抢购的商品正好变成了热点商品,此时应该走排队的方式抢单,否则商品数量会发生不精准问题
*/
5.如果是热点商品,则走热点商品抢单流程(kafka进行排队处理)
6.判断该商品用户是否已经排队,如果没有排队,则进入排队,如果已经排队,则提示用户正在排队
/*
1.校验用户令牌,如果不通过直接结束程序提示用户
2.令牌校验通过,从Redis中获取用户在24小时内是抢购过该商品,如果抢购过直接结束程序并提示用户
3.如果符合购买该商品条件,则校验该商品是否是热点商品,如果不是,直接请求后台下单
4.如果是热点商品,并且库存>0,校验用户是否已经在排队,使用redis的incr自增判断排队次数可以去除重复排队
5.如果没有排队,则向Kafka发送消息实现排队
*/
7.下单过程交给订单系统,订单系统通过队列订阅读取用户下单信息,并进行下单
总结:
Redis用来存放热点数据和信息,便于我们查询,当我们查询到是热点数据的时候,我们就是用kafka进行排队处理,这样可以缓解数据库带来的压力。