在rabbitmq的官网下载延迟队列的插件,注意与rabbitmq的版本相对应
地址:https://www.rabbitmq.com/community-plugins.htm
下载好插件之后安装到rabbitMQ中,具体方法很简单百度一下
下面是demo:
pom文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.liaoxiang</groupId>
<artifactId>delayed_mq</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
</project>
配置文件:
server:
port: 8080
spring:
rabbitmq:
host: 192.168.8.128
port: 5672
username: guest
password: guest
配置类:
package com.liaoxiang.delayed.config;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMqConfig {
@Value("${spring.rabbitmq.host}")
private String host;
@Value("${spring.rabbitmq.port}")
private int port;
@Value("${spring.rabbitmq.username}")
private String userName;
@Value("${spring.rabbitmq.password}")
private String password;
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(host, port);
cachingConnectionFactory.setUsername(userName);
cachingConnectionFactory.setPassword(password);
cachingConnectionFactory.setVirtualHost("/");
cachingConnectionFactory.setPublisherConfirms(true);
return cachingConnectionFactory;
}
@Bean
public RabbitTemplate rabbitTemplate() {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory());
return rabbitTemplate;
}
}
package com.liaoxiang.delayed.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.CustomExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class QueueConfig {
/**
* 声明延迟交换机
* @return
*/
@Bean
public CustomExchange delayExchange() {
Map<String, Object> args = new HashMap<>();
args.put("x-delayed-type", "direct");
return new CustomExchange("delayed_exchange", "x-delayed-message", true, false, args);
}
/**
* 第一次分账的队列
* @return
*/
@Bean
public Queue queue1() {
return new Queue("multi_profit_sharing1", true);
}
/**
* 第二分账的队列
* @return
*/
@Bean
public Queue queue2() {
return new Queue("multi_profit_sharing2", true);
}
/**
* 将两个队列绑定到延迟交换机
* @return
*/
@Bean
public Binding binding1() {
return BindingBuilder.bind(queue1()).to(delayExchange()).with("delayed_key1").noargs();
}
@Bean
public Binding binding2() {
return BindingBuilder.bind(queue2()).to(delayExchange()).with("delayed_key2").noargs();
}
}
这里也可以只使用一个队列,只是测试一下根据不同的routingKey路由到不同的队列而已
消息生产者:
package com.liaoxiang.delayed.service;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MessageServiceImpl {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 发送消息到延迟交换机
*
* @param routingKey
* @param msg
* @param delayTime 时间单位为s
*/
public void sendMsg(String routingKey, Object msg, int delayTime) {
rabbitTemplate.convertAndSend(
"delayed_exchange",
routingKey,
msg,
message -> {
message.getMessageProperties().setHeader("x-delay", 1000 * delayTime);
return message;
}
);
}
}
消息消费者:
package com.liaoxiang.delayed.listener;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
public class MessageReceiver {
/**
* 第一次分账
* @param msg
*/
@RabbitListener(queues = "multi_profit_sharing1")
public void receive1(String msg) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("第一次分账,消息接收时间:"+sdf.format(new Date()));
System.out.println("接收到的消息:"+msg);
}
/**
* 第二次分账
* @param msg
*/
@RabbitListener(queues = "multi_profit_sharing2")
public void receive2(String msg) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("第二次分账,消息接收时间:"+sdf.format(new Date()));
System.out.println("接收到的消息:"+msg);
}
}
测试方法:
package com.liaoxiang.delayed;
import com.liaoxiang.delayed.service.MessageServiceImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.text.SimpleDateFormat;
import java.util.Date;
@RunWith(SpringRunner.class)
@SpringBootTest
public class RabbitmqApplicationTests {
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Autowired
private MessageServiceImpl messageService;
@Test
public void send1() {
String time = sdf.format(new Date());
messageService.sendMsg("delayed_key1", "第一次分账,请求时间:" + time, 10);
}
@Test
public void send2() {
String time = sdf.format(new Date());
messageService.sendMsg("delayed_key2", "第二次分账,请求时间:" + time,20);
}
}