很简单的实现方法,大家帮忙看看能不能继续完善。
步骤:
- 添加rabbitmq配置
- 添加rabbitmq配置类
- 添加订单生产者
- 添加订单消费者(修改状态)
1、添加rabbitmq配置
注意一定要开启手动应答,不然可能会报错
spring
rabbitmq:
host: 你的地址
port: 5672
username: admin
password: admin
listener:
simple:
# 开启手动应答
acknowledge-mode: manual
2、添加rabbitmq配置类
下面这段代码看着有点繁琐,我解释一下逻辑关系。
1、声明订单交换机、声明订单队列,在订单队列中声明绑定的死信交换机
2、订单交换机Binding订单队列
3、声明死信交换机、队列并且Binding
package com.lutao.config;
import com.rabbitmq.client.AMQP;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
@Configuration
public class RabbitMqConfig {
public static final String ORDER_QUEUE = "order_queue";
public static final String ORDER_EXCHANGE = "order_exchange";
public static final String ORDER_DEAD_EXCHANGE = "order_dead_exchange";
public static final String ORDER_DEAD_QUEUE = "order_dead_queue";
public static final String ORDER_ROUTING = "order_routing";
public static final String ORDER_DEAD_ROUTING = "order_dead_routing";
/**
* 订单交换机
*/
@Bean("orderExchange")
public DirectExchange getOrderExchange(){
return new DirectExchange(ORDER_EXCHANGE);
}
/**
* 订单队列
*/
@Bean("orderQueue")
public Queue getOrderQueue(){
HashMap<String, Object> map = new HashMap<>(3);
map.put("x-dead-letter-exchange",ORDER_DEAD_EXCHANGE);
map.put("x-dead-letter-routing-key",ORDER_DEAD_ROUTING);
map.put("x-message-ttl",30000);
return QueueBuilder.durable(ORDER_QUEUE).withArguments(map).build();
}
/**
* 订单交换机与订单队列绑定
*/
@Bean
public Binding oExchangeBindingO(
@Qualifier("orderExchange") DirectExchange exchange,
@Qualifier("orderQueue") Queue queue
){
return BindingBuilder.bind(queue).to(exchange).with(ORDER_ROUTING);
}
/**
* 死信交换机
*/
@Bean("orderDeadExchange")
public DirectExchange getOrderDeadExchange(){
return new DirectExchange(ORDER_DEAD_EXCHANGE);
}
/**
* 死信队列
*/
@Bean("orderDeadQueue")
public Queue getOrderDradQueue(){
return new Queue(ORDER_DEAD_QUEUE,true,false,false,null);
}
@Bean
public Binding deadExchangeDead(
@Qualifier("orderDeadExchange") DirectExchange exchange,
@Qualifier("orderDeadQueue") Queue queue
){
return BindingBuilder.bind(queue).to(exchange).with(ORDER_DEAD_ROUTING);
}
}
3、添加订单生产者
在插入新订单数据时,向订单队列发送一条延迟时间为30秒的信息
@Override
@Transactional
public void insertOrder(OT ot) {
Orders orders = new Orders();
BeanUtils.copyProperties(ot, orders);
List<CartVO> listCart = ot.getListCart();
//生成订单号
String onumber = get16UUID();
orders.setOnumber(onumber);
ordersMapper.insertOrder(orders);
//删除购物车
Integer[] cids = new Integer[listCart.size()];
for (int i = 0; i < listCart.size(); i++) {
CartVO cartVO = listCart.get(i);
ordersMapper.insertGoods(onumber, cartVO);
cids[i] = listCart.get(i).getCid();
}
//发送到队列中
//将订单编号发送到队列中
log.info("将订单编号发送到订单队列中");
rabbitTemplate.convertAndSend(RabbitMqConfig.ORDER_EXCHANGE,RabbitMqConfig.ORDER_ROUTING,orders.getOnumber());
cartMapper.deleteCid(cids);
}
4、死信队列消费者处理信息文章来源:https://www.toymoban.com/news/detail-679328.html
30秒后订单进入死信队列,由消费者消费,根据订单号查询订单的状态如果还是0(未支付)则将状态更新成(2)已取消。文章来源地址https://www.toymoban.com/news/detail-679328.html
@Autowired
private OrdersMapper ordersMapper;
/**
* 判断是否在规定时间内支付
*
* @param message
* @param channel
* @throws IOException
*/
@RabbitListener(queues = RabbitMqConfig.ORDER_DEAD_QUEUE)
public void receive(Message message, Channel channel) throws IOException {
log.info("订单进入死信队列");
String msg = new String(message.getBody());
log.info("订单号:"+msg);
OrderPageRequest request = new OrderPageRequest();
request.setOnumber(msg);
Integer status = ordersMapper.getStatusByONumber(msg);
if (status != null && status == 0){
ordersMapper.updateStatus(msg,2);
}
//应答
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
}
到了这里,关于超简单的RabbitMq实现订单超时自动取消的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!