前提条件:RabbitMQ安装
1.Windows下RabbitMq安装
windows环境下安装RabbitMQ(超详细),
2.linux下
Linux下安装RabbitMQ,点我跳转;
无论是windwos还是linux安装的rabbit,开始编写代码前请确认rabbit运行状态。
以上是rabbitmq默认的可视化界面访问地址,账号密码默认为:guest/guest
如有需要修改默认账号密码:请点此链接跳转
一切准备就绪,开始发功
======================我是一条发功分界线=================================
1.给我们的maven项目添加依赖(springboot + maven)
打开我们项目的pom.xml,在dependencies标签中添加如下代码
<!-- Rabbit MQ 依赖 begin -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Rabbit MQ 依赖 end -->
添加了以后记得maven重新加载一下哈,不然后面添加的代码有可能会报依赖错误。
2.添加rabbitmq的配置.springboot可以放在bootstrap.yml
spring:
rabbitmq:
host: slave.taskwall.net #rabbit安装地址
port: 5672 #端口,默认为5672
username: guest
password: guest
virtual-host: / #请注意这里,如果没有配对有可能会在启动时报错,报连不上rabbit
virtual-host:
具体配置应为username对应的host,具体可以登录rabbitmq,查看。
登录rabbit界面管理,IP:PORT:15672,对应的账号登录后找到admintab页面
填写账户对应virtual--host,如图所示:
-----------------------------------------至此,配置完成,开发代码部分-----------------------------------------
1.----------------新建RabbitMQConfiguration.java
*********************用户队列的配置:队列名称,交换机名称,死信队列************
你可以先照搬这个代码,当做demo
package com.taskwall.member.util;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* @author Gemini Wong
* @date 2022-03-23 22:46
*/
@Configuration
public class RabbitMQConfiguration {
//队列名称
public final static String orderQueue = "order_queue";
//交换机名称
public final static String orderExchange = "order_exchange";
// routingKey
public final static String routingKeyOrder = "routing_key_order";
//死信消息队列名称
public final static String dealQueueOrder = "deal_queue_order";
//死信交换机名称
public final static String dealExchangeOrder = "deal_exchange_order";
//死信 routingKey
public final static String deadRoutingKeyOrder = "dead_routing_key_order";
//死信队列 交换机标识符
public static final String DEAD_LETTER_QUEUE_KEY = "x-dead-letter-exchange";
//死信队列交换机绑定键标识符
public static final String DEAD_LETTER_ROUTING_KEY = "x-dead-letter-routing-key";
@Autowired
private CachingConnectionFactory connectionFactory;
@Bean
public Queue orderQueue() {
// 将普通队列绑定到死信队列交换机上
Map<String, Object> args = new HashMap<>(2);
//args.put("x-message-ttl", 5 * 1000);//直接设置 Queue 延迟时间 但如果直接给队列设置过期时间,这种做法不是很灵活
//这里采用发送消息动态设置延迟时间,这样我们可以灵活控制
args.put(DEAD_LETTER_QUEUE_KEY, dealExchangeOrder);
args.put(DEAD_LETTER_ROUTING_KEY, deadRoutingKeyOrder);
return new Queue(RabbitMQConfiguration.orderQueue, true, false, false, args);
}
//声明一个direct类型的交换机
@Bean
DirectExchange orderExchange() {
return new DirectExchange(RabbitMQConfiguration.orderExchange);
}
//绑定Queue队列到交换机,并且指定routingKey
@Bean
Binding bindingDirectExchangeDemo5( ) {
return BindingBuilder.bind(orderQueue()).to(orderExchange()).with(routingKeyOrder);
}
//创建配置死信队列
@Bean
public Queue deadQueueOrder() {
Queue queue = new Queue(dealQueueOrder, true);
return queue;
}
//创建死信交换机
@Bean
public DirectExchange deadExchangeOrder() {
return new DirectExchange(dealExchangeOrder);
}
//死信队列与死信交换机绑定
@Bean
public Binding bindingDeadExchange() {
return BindingBuilder.bind(deadQueueOrder()).to(deadExchangeOrder()).with(deadRoutingKeyOrder);
}
}
2.----------------业务部分将订单加入队列
//Rabbit延时队列,处理订单自动取消
this.rabbitTemplate.convertAndSend(
RabbitMQConfiguration.orderExchange,
RabbitMQConfiguration.routingKeyOrder,
twOrder.getOrderId()
, message -> {
message.getMessageProperties().setExpiration(1000 * 10 + "");
return message;
});
rabbitTemplate需要引入一下jar包:
@Resource
private AmqpTemplate rabbitTemplate;
好了。到此已经做掉了新增订单时,将订单放入mq的队列中,其中setExpiration是设置过期时间。你可以设置成30分钟或者15分钟,看业务需要,我们做demo的时候可以设置成5s/10s(单位是毫秒,所以要乘以1000)
2.----------------订单到时间后,触发自动取消
附上代码:OrderFailureListener
值得注意的是这边的注解@RabbitListener( queues = RabbitMQConfiguration.dealQueueOrder )
也就是对应的是RabbitMQConfiguration配置中的一个队列
也就是说你有多个业务需要延时操作的,你就可以创建多个队列来实现
package com.taskwall.member.util;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Map;
/**
* @author Gemini Wong
* @date 2022-03-23 22:51
*/
@Component
public class OrderFailureListener {
@RabbitListener(
queues = RabbitMQConfiguration.dealQueueOrder
)
public void process(String order, Message message, @Headers Map<String, Object> headers, Channel channel) throws IOException {
// 判断订单是否已经支付,如果支付则;否则,取消订单(逻辑代码省略)
System.out.println("订单编号:" + order + ";因超时自动取消");
}
}
订单取消的业务逻辑这边就不加上去了。
无非就是先判断订单是否成功支付,没有支付就取消订单。
*******************************2022-04-12更新已完成***********************************