1.秒杀接口优化思路
秒杀接口优化的核心就是减少数据库访问。
-
系统初始化将商品库存数量加载到redis
-
收到请求redis预减库存,库存不足直接返回,否则直接进入3.
好处:如果库存只有10,10个请求以后的所有请求直接返回秒杀失败,直接挡住了很多请求,不会继续往下执行,大大提高了效率。 -
请求入队rabbitMQ,立即返回排队中
比如:12306购票的时候,下订单就会返回正在排队中,如果抢购成功就会返回结果。 -
请求出队,生成订单,减少库存
-
客服端轮询是否秒杀成功
2.rabbitMQ的集成
- 添加rabbitMQ的依赖
- 添加rabbitMQ的配置文件
Direct模式:
该模式下不需要添加交换机,只有一个消息队列。
3. 创建生成消息队列的类
4. 创建消息生产者,往指定的消息队列里添加消息
5. 创建消息消费者,从指定的消息队列里获取消息并处理
生产者不是直接将消息发送到队列中的,而是经过一个Exchanger交换机,消费者将消息发送到交换机,由交换机决定发送到哪个队列中。Exchanger交换机具有4种模式:上面的Direct模式是最简单的模式。
Topic模式
这样topic模式就能实现发送一条消息到多个队列中去了
- 创建多个topic_queue队列,创建一个topic_exchange
- 通过topic_exchange交换机将topic_queue1于key1进行绑定,topic_queue2与key2进行绑定
Fanout模式
广播配置模式
- 创建多个队列,创建一个Fanout_exchange,绑定所有的消息队列到交换机
- 消息发送者发送的消息就会添加到所有的消息队列中了
Header模式
header模式需要满足一定条件才会往队列里添加消息
总的来看,rabbitMQ的使用分为3步:
(1)创建消息队列Queue
(2)创建交换机Exchanger
(3)将交换机与消息队列绑定Binding (消息队列与交换机绑定具有4中模式)
3.秒杀商品模块优化
原来在秒杀模块需要访问4次数据库:
(1)查库存
(2)判断是否重复秒杀(从redis中查)
(3)减库存(先修改数据库,再删除缓存)
(4)添加订单
(5)添加秒杀订单
如果并发量较大,就会大大增加数据库的压力。所以我们使用rabbitMQ将秒杀模块改成异步下单的模式。
3.1 秒杀模块的实现
1.系统初始化(Spring扫描秒杀controller)的时候,将所有秒杀商品的库存数量添加到缓存中。缓存设置为永久不失效
MiaoshaController实现InitializingBean接口,并且实现afterPropertiesSet方法,加载所有秒杀商品库存到redis中
@Controller
@RequestMapping("/miaosha")
public class MiaoshaController implements InitializingBean {
/**
* 系统初始化
* */
public void afterPropertiesSet() throws Exception {
//获取所有秒杀商品
List<GoodsVo> goodsList = goodsService.listGoodsVo();
if(goodsList == null) {
return;
}
//将所有秒杀商品的库存添加到redis缓存中
for(GoodsVo goods : goodsList) {
redisService.set(GoodsKey.getMiaoshaGoodsStock, ""+goods.getId(), goods.getStockCount());
localOverMap.put(goods.getId(), false);
}
}
}
2.秒杀抢购时,通过查询redis库存是否足够。如果足够首先在redis预减库存,库存不足,直接返回秒杀失败。使用消息队列