环境介绍
服务器: 阿里云Centos7.4
JDK版本: jdk1.8
RocketMQ版本: 4.5.1
安装RocketMQ
wget https://archive.apache.org/dist/rocketmq/4.5.1/rocketmq-all-4.5.1-bin-release.zip
启动nameserver
# 1.启动
NameServermqnamesrv
# 2.查看启动日志
tail -f ~/logs/rocketmqlogs/namesrv.log
启动broker
mqbroker -n localhost:9876
# 2.查看启动日志
tail -f ~/logs/rocketmqlogs/broker.log
基于RocketMQ设计秒杀实现逻辑

这里的超时支付使用redis过期回调处理
核心代码 :
@Component
@RocketMQMessageListener(topic = "springboot-mq",consumerGroup = "springboot-mq-consumer-1")
public class Consumer implements RocketMQListener<OrderInfo> {
@Resource
OrderInfoMapper orderInfoMapper;
@Resource
WarehouseMapper warehouseMapper;
@Autowired
StringRedisTemplate redisTemplate;
@Override
public void onMessage(OrderInfo orderInfo) {
System.out.println("消费订单消息");
orderInfoMapper.insert(orderInfo);
System.out.println(orderInfo.getId()+"订单入库");
Warehouse warehouse = warehouseMapper.selectByPrimaryKey(orderInfo.getCommodity());
warehouse.setNum(warehouse.getNum()-1);
System.out.println("扣减库存");
warehouseMapper.updateByPrimaryKey(warehouse);
redisTemplate.opsForValue().set("order:"+orderInfo.getId(),"",15,TimeUnit.SECONDS);
}
}
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
@Resource
OrderInfoMapper orderInfoMapper;
@Resource
WarehouseMapper warehouseMapper;
@Autowired
StringRedisTemplate redisTemplate;
public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
public void onMessage(Message message, byte[] pattern) {
String expireKey = message.toString();
if (expireKey.startsWith("order:")){
Integer orderId = Integer.valueOf(expireKey.replace("order:",""));
OrderInfo orderInfo = orderInfoMapper.selectByPrimaryKey(orderId);
orderInfo.setStatus(2);
orderInfoMapper.updateByPrimaryKeySelective(orderInfo);
System.out.println("订单失效,库存还原+1");
Warehouse warehouse = warehouseMapper.selectByPrimaryKey(orderInfo.getCommodity());
warehouse.setNum(warehouse.getNum()+1);
warehouseMapper.updateByPrimaryKey(warehouse);
redisTemplate.opsForValue().increment("num");
}
}
}
@Service
public class OrderService {
@Resource
OrderInfoMapper orderInfoMapper;
@Autowired
StringRedisTemplate redisTemplate;
@Autowired
private RocketMQTemplate rocketMQTemplate;
public Integer submitOrder(Integer commodity){
Integer id = getOrderNum();
OrderInfo orderInfo = new OrderInfo();
orderInfo.setId(id);
orderInfo.setCommodity(commodity);
orderInfo.setStatus(0);
boolean flag = subtractStock(1);
if(!flag){
return -1;
}
rocketMQTemplate.convertAndSend("springboot-mq",orderInfo);
return id;
}
public Integer pay(Integer id){
Boolean delete = redisTemplate.delete("order:" + id);
System.out.println(delete);
if(delete){
return 1;
}
return 0;
}
/**
* 模拟订单号
* @return
*/
public Integer getOrderNum(){
Random random = new Random();
return random.nextInt(10000);
}
/**
* Redis乐观锁实现秒杀
* @param num
* @return
*/
public boolean subtractStock(Integer num) {
String key = "num";
redisTemplate.setEnableTransactionSupport(true);
redisTemplate.watch(key);
Object value = redisTemplate.opsForValue().get(key);
if (value == null) {
//前提 提前将商品库存放入缓存 ,如果缓存不存在,视为没有该商品
return false;
}
//先检查 库存是否充足
Integer stock = Integer.valueOf(value.toString());
if (stock < num) {
System.out.println("库存不足");
return false;
}
redisTemplate.multi();
Long newStock = redisTemplate.opsForValue().increment(key, -num.longValue());
System.out.println(newStock);
List<Object> exec = redisTemplate.exec();
if(exec!=null && exec.size()>0){
return true;
}
return false;
}
}
873

被折叠的 条评论
为什么被折叠?



