Spring Boot整合RabbitMQ实现延时队列
1. 环境准备
在开始之前,需要确保以下环境已经准备好:
- JDK 1.8+
- Maven 3.0+
- RabbitMQ 3.0+
2. 引入依赖
在pom.xml
文件中添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
3. 配置 RabbitMQ
在application.properties
文件中添加以下配置:
# RabbitMQ 配置
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
4. 创建延时队列
在 RabbitMQ 中,可以通过设置消息的过期时间来实现延时队列。具体操作如下:
- 创建一个普通的队列
- 设置队列的 TTL(Time To Live)属性
- 创建一个交换器(Exchange)
- 将队列绑定到交换器上,并设置 Routing Key
代码实现如下:
@Configuration
public class RabbitMQConfig {
// 订单队列
public static final String ORDER_QUEUE_NAME = "order.queue";
// 订单交换器
public static final String ORDER_EXCHANGE_NAME = "order.exchange";
// 订单 Routing Key
public static final String ORDER_ROUTING_KEY = "order.routingKey";
// 延时队列 TTL(单位:毫秒)
public static final int DELAY_TIME = 10 * 1000;
// 创建订单队列
@Bean
public Queue orderQueue() {
Map<String, Object> args = new HashMap<>();
// 设置队列的 TTL 属性
args.put("x-message-ttl", DELAY_TIME);
// 设置队列中的消息过期后进入的交换器
args.put("x-dead-letter-exchange", ORDER_EXCHANGE_NAME);
// 设置队列中的消息过期后进入的 Routing Key
args.put("x-dead-letter-routing-key", ORDER_ROUTING_KEY);
return new Queue(ORDER_QUEUE_NAME, true, false, false, args);
}
// 创建订单交换器
@Bean
public DirectExchange orderExchange() {
return new DirectExchange(ORDER_EXCHANGE_NAME);
}
// 将订单队列绑定到订单交换器上
@Bean
public Binding orderBinding() {
return BindingBuilder.bind(orderQueue()).to(orderExchange()).with(ORDER_ROUTING_KEY);
}
}
5. 发送延时消息
在需要发送延时消息的地方,可以注入AmqpTemplate
对象,然后使用convertAndSend
方法发送消息。具体代码如下:
@Component
public class OrderService {
@Autowired
private AmqpTemplate amqpTemplate;
public void createOrder(Order order) {
// 发送延时消息
amqpTemplate.convertAndSend(RabbitMQConfig.ORDER_QUEUE_NAME, order, message -> {
message.getMessageProperties().setExpiration(String.valueOf(RabbitMQConfig.DELAY_TIME));
return message;
});
}
}
上述代码中,我们通过amqpTemplate.convertAndSend()
方法发送了一条延时消息。在发送消息之前,我们可以通过message.getMessageProperties().setExpiration()
方法设置消息的过期时间。
6. 接收延时消息
在需要接收延时消息的地方,需要定义一个@RabbitListener
注解的方法来监听队列中的消息。具体代码如下:
@Component
public class OrderConsumer {
@RabbitListener(queues = RabbitMQConfig.ORDER_QUEUE_NAME)
public void handleMessage(Order order) {
System.out.println("接收到订单消息:" + order);
}
}
7. 测试代码
在编写完上述代码后,我们可以编写测试代码来验证延时队列的功能是否正常。具体代码如下:
@SpringBootTest
@RunWith(SpringRunner.class)
public class OrderServiceTest {
@Autowired
private OrderService orderService;
@Test
public void testCreateOrder() throws InterruptedException {
Order order = new Order();
order.setOrderId("123456");
order.setAmount(100);
orderService.createOrder(order);
Thread.sleep(20 * 1000);
}
}
运行上述测试代码后,我们可以在控制台中看到如下输出:
接收到订单消息:Order(orderId=123456, amount=100)
从输出中可以看出,我们成功地接收到了延时消息,延时队列的功能正常。