org.springframework.boot spring-boot-starter-amqp 2.7.7
@Component @Slf4j public class RabbitmqConfig implements InitializingBean { @Resource private RabbitTemplate rabbitTemplate; @Override public void afterPropertiesSet() throws Exception { log.info("初始化配置rabbitmq配置"); // rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter(new ObjectMapper())); rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() { @Override public void confirm(CorrelationData correlationData, boolean b, String s) { if(!b) { log.error("发送消息到mq失败,原因:{}",s); } } }); rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() { @Override public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) { log.error("消息返回回调触发,交换机:{},路由:{},消息内容:{},原因:{}",exchange,routingKey,message,replyText); } }); } }
通过@Bean注入MessageConverter,保证消息的正确传输
@Bean public MessageConverter jsonMessageConverter(ObjectMapper objectMapper) { return new Jackson2JsonMessageConverter(objectMapper); }
修改后的代码
@Override //关于事务注解 public Result seckillVoucher(Long voucherId) { // 1,执行lua脚本,lua脚本用于判断库存是否充足,扣库存操作 Long userId=UserHolder.getUser().getId(); long orderId=redisIDworker.nextId("order"); //执行此操作前保证,用户查看优惠券的请求,和添加优惠券时 已经将秒杀优惠圈的库存数量添加到了redis中 Long result=stringRedisTemplate.execute( SECKILL_SCRIPT, Collections.emptyList(), voucherId.toString(), userId.toString(), String.valueOf(orderId) ); //获取lua脚本返回值 int r=result.intValue(); if(r!=0) { return Result.fail(r==1?"库存不足":"不能重复下单"); } // //获取代理对象 // IVoucherOrderService proxy= (IVoucherOrderService) AopContext.currentProxy(); //异步写数据库 VoucherOrder voucherOrder = new VoucherOrder(); voucherOrder.setId(orderId); voucherOrder.setUserId(userId); voucherOrder.setVoucherId(voucherId); rabbitTemplate.convertAndSend(SaveVoucherConstants.SECKILL_VOUCHER_SAVE_QUEUE,voucherOrder); log.info("发送保存秒杀券订单信息成功:{}",orderId); return Result.ok("seckSuccess"); }
监听器
@Component @Slf4j public class AsyncSaveVoucherListener { @Resource private IVoucherOrderService voucherOrderService; @Resource private ISeckillVoucherService seckillVoucherService; @RabbitListener(queuesToDeclare = {@Queue(name= SaveVoucherConstants.SECKILL_VOUCHER_SAVE_QUEUE)}) public void AsyncSave(VoucherOrder voucherOrder) { log.info("接收到存储订单信息的消息,{}", JSON.toJSON(voucherOrder).toString()); boolean success = seckillVoucherService.update().setSql("stock=stock-1").eq("voucher_id", voucherOrder.getVoucherId()).gt("stock", 0).update(); voucherOrderService.save(voucherOrder); log.info("订单信息存储完成?{}",success); } }