1. 初始化配置
1.1 引入依赖
<!--spring整合RabbitMQ-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--spring-web-->
<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>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>test</scope>
</dependency>
1.2 连接RabbitMQ配置文件
server:
port: 8082
spring:
rabbitmq:
port: 5672
host: 192.168.200.100
username: admin
password: admin
2. Fanout模式
2.1 创建配置文件
创建交换机和队列并进行绑定
此配置文件放到生产端或消费端都可以
/**
* @author: mingan.xie
* @since: 2021/3/22
* @history: 1.2021/3/22 created by xma
*/
@Configuration
public class RabbitMQConfigFanout {
// 1: 声明交换机
@Bean
public FanoutExchange fanoutExchange(){
return new FanoutExchange("fanout_order_product");
}
// 2: 声明队列
// durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
// exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
// autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
@Bean
public Queue duanxinQueue(){
return new Queue("duanxin.fanout.queue", true, false, false);
}
@Bean
public Queue emailQueue(){
return new Queue("email.fanout.queue", true, false, false);
}
@Bean
public Queue smsQueue(){
return new Queue("sms.fanout.queue", true, false, false);
}
// 3: 绑定对用关系
@Bean
public Binding smsBinding(){
return BindingBuilder.bind(smsQueue()).to(fanoutExchange());
}
@Bean
public Binding emailBinding(){
return BindingBuilder.bind(emailQueue()).to(fanoutExchange());
}
@Bean
public Binding duanxinBinding(){
return BindingBuilder.bind(duanxinQueue()).to(fanoutExchange());
}
}
2.2 创建生产者
@Component
public class ProductFanout {
@Resource
private RabbitTemplate rabbitTemplate;
public void makerOrderFanout(){
// 参数1: 交换机名称
String exchangeName = "fanout_order_product";
// 参数2: direct 和 topic 模式下的路由key / 无交换机模式下的路由名称
String routingKey = "";
// 参数3: 消息体
String orderId = UUID.randomUUID().toString();
rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId);
}
}
2.3 创建消费者
短信消费者
@Component
@RabbitListener(queues = {"duanxin.fanout.queue"})
public class FanoutDuanxinConsumer {
@RabbitHandler
public void reviceMessage(String message){
System.out.println("fanout Duanxin 接收到了消息:" + message);
}
}
Email消费者
@Component
@RabbitListener(queues = {"email.fanout.queue"})
public class FanoutEmailConsumer {
@RabbitHandler
public void reviceMessage(String message){
System.out.println("fanout Email 接收到了消息:" + message);
}
}
Sms消费者
@Component
@RabbitListener(queues = {"sms.fanout.queue"})
public class FanoutSmsConsumer {
@RabbitHandler
public void reviceMessage(String message){
System.out.println("fanout Sms 接收到了消息:" + message);
}
}
2.4 调用测试类
@SpringBootTest
class SpringBootRabbitmqProducerApplicationTests {
@Resource
private ProductFanout productFanout;
@Test
void contextLoads1() {
productFanout.makerOrderFanout();
}
}
3. Direct模式
3.1 创建配置文件
创建交换机和队列并进行绑定
此配置文件放到生产端或消费端都可以
/**
* @author: mingan.xie
* @since: 2021/3/22
* @history: 1.2021/3/22 created by xma
*/
@Configuration
public class RabbitMQConfigDirect {
// 1: 声明交换机
@Bean
public DirectExchange directExchange(){
return new DirectExchange("direct_order_product");
}
// 2: 声明队列
// durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
// exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
// autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
@Bean
public Queue directduanxinQueue(){
return new Queue("duanxin.direct.queue", true, false, false);
}
@Bean
public Queue directemailQueue(){
return new Queue("email.direct.queue", true, false, false);
}
@Bean
public Queue directsmsQueue(){
return new Queue("sms.direct.queue", true, false, false);
}
// 3: 绑定对用关系
// with(): 绑定对应的路由key *:一个字符 #: 一个或多个字符
@Bean
public Binding directsmsBinding(){
return BindingBuilder.bind(directsmsQueue()).to(directExchange()).with("sms");
}
@Bean
public Binding directemailBinding(){
return BindingBuilder.bind(directemailQueue()).to(directExchange()).with("email");
}
@Bean
public Binding directduanxinBinding(){
return BindingBuilder.bind(directduanxinQueue()).to(directExchange()).with("duanxin");
}
}
3.2 创建生产者
@Component
public class ProductFanout {
@Resource
private RabbitTemplate rabbitTemplate;
public void makerOrderDirect(){
// 参数1: 交换机名称
String exchangeName = "direct_order_product";
// 参数2: direct 和 topic 模式下的路由key / 无交换机模式下的路由名称
// 参数3: 消息体
String orderId = UUID.randomUUID().toString();
rabbitTemplate.convertAndSend(exchangeName, "sms", orderId);
rabbitTemplate.convertAndSend(exchangeName, "email", orderId);
System.out.println("路由key: sms, email");
}
}
3.3 创建消费者
短信消费者
@Component
@RabbitListener(queues = {"duanxin.direct.queue"})
public class DirectDuanxinConsumer {
@RabbitHandler
public void reviceMessage(String message){
System.out.println("direct Duanxin 接收到了消息:" + message);
}
}
Email消费者
@Component
@RabbitListener(queues = {"email.direct.queue"})
public class DirectEmailConsumer {
@RabbitHandler
public void reviceMessage(String message){
System.out.println("direct Email 接收到了消息:" + message);
}
}
Sms消费者
@Component
@RabbitListener(queues = {"sms.direct.queue"})
public class DirectSmsConsumer {
@RabbitHandler
public void reviceMessage(String message){
System.out.println("direct Sms 接收到了消息:" + message);
}
}
3.4 调用测试类
@SpringBootTest
class SpringBootRabbitmqProducerApplicationTests {
@Resource
private ProductFanout productFanout;
@Test
void contextLoads2() {
productFanout.makerOrderDirect();
}
}
4. Topic模式
4.1 创建配置文件
创建交换机和队列并进行绑定
此配置文件放到生产端或消费端都可以
/**
* @author: mingan.xie
* @since: 2021/3/22
* @history: 1.2021/3/22 created by xma
*/
@Configuration
public class RabbitMQConfigTopic {
// 1: 声明交换机
@Bean
public TopicExchange topicExchange(){
return new TopicExchange("topic_order_product");
}
// 2: 声明队列
// durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
// exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
// autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
@Bean
public Queue topicduanxinQueue(){
return new Queue("duanxin.topic.queue", true, false, false);
}
@Bean
public Queue topicemailQueue(){
return new Queue("email.topic.queue", true, false, false);
}
@Bean
public Queue topicsmsQueue(){
return new Queue("sms.topic.queue", true, false, false);
}
// 3: 绑定对用关系
// with(): 绑定对应的路由key *:一个字符 #: 一个或多个字符
@Bean
public Binding topicsmsBinding(){
return BindingBuilder.bind(topicsmsQueue()).to(topicExchange()).with("*.topic.#");
}
@Bean
public Binding topicemailBinding(){
return BindingBuilder.bind(topicemailQueue()).to(topicExchange()).with("#.topic.#");
}
@Bean
public Binding topicduanxinBinding(){
return BindingBuilder.bind(topicduanxinQueue()).to(topicExchange()).with("com.#");
}
}
4.2 创建生产者
@Component
public class ProductFanout {
@Resource
private RabbitTemplate rabbitTemplate;
public void makerOrderTopic(){
// 参数1: 交换机名称
String exchangeName = "topic_order_product";
// 参数2: direct 和 topic 模式下的路由key / 无交换机模式下的路由名称
String routingKey = "com.xxx.topic";
// 参数3: 消息体
String orderId = UUID.randomUUID().toString();
rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId);
System.out.println("路由key:" + routingKey);
}
}
4.3 创建消费者
短信消费者
@Component
@RabbitListener(queues = {"duanxin.topic.queue"})
public class TopicDuanxinConsumer {
@RabbitHandler
public void reviceMessage(String message){
System.out.println("topic Duanxin 接收到了消息:" + message);
}
}
Email消费者
@Component
@RabbitListener(queues = {"email.topic.queue"})
public class TopicEmailConsumer {
@RabbitHandler
public void reviceMessage(String message){
System.out.println("topic Email 接收到了消息:" + message);
}
}
Sms消费者
@Component
@RabbitListener(queues = {"sms.topic.queue"})
public class TopicSmsConsumer {
@RabbitHandler
public void reviceMessage(String message){
System.out.println("topic Sms 接收到了消息:" + message);
}
}
4.4 调用测试类
@SpringBootTest
class SpringBootRabbitmqProducerApplicationTests {
@Resource
private ProductFanout productFanout;
@Test
void contextLoads3() {
productFanout.makerOrderTopic();
}
}
5. 设置消息过期时间
5.1 设置队列整体消息过期时间
创建配置文件
/**
* @author: mingan.xie
* @since: 2021/3/22
* @history: 1.2021/3/22 created by xma
*/
@Configuration
public class RabbitMQConfigTTL {
// 1: 声明交换机
@Bean
public TopicExchange ttlTopicExchange(){
return new TopicExchange("ttl_topic_order_product");
}
// 2: 声明队列
// durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
// exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
// autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
@Bean
public Queue ttlTopicduanxinQueue(){
HashMap<String, Object> args = new HashMap<>();
// 给队列设置消息过期时间:毫秒值
args.put("x-message-ttl", 5000);
return new Queue("ttl.duanxin.topic.queue", true, false, false, args);
}
// 3: 绑定对用关系
@Bean
public Binding ttlTopicsmsBinding(){
return BindingBuilder.bind(ttlTopicduanxinQueue()).to(ttlTopicExchange()).with("ttl");
}
}
创建生产者
@Component
public class ProductFanout {
@Resource
private RabbitTemplate rabbitTemplate;
public void makerOrderTopicTtl(){
// 参数1: 交换机名称
String exchangeName = "ttl_topic_order_product";
// 参数2: direct 和 topic 模式下的路由key / 无交换机模式下的路由名称
String routingKey = "ttl";
// 参数3: 消息体
String orderId = UUID.randomUUID().toString();
rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId);
System.out.println("路由key:" + routingKey);
}
}
调用测试类
@SpringBootTest
class SpringBootRabbitmqProducerApplicationTests {
@Resource
private ProductFanout productFanout;
@Test
void contextLoads4() {
productFanout.makerOrderTopicTtl();
}
}
5.2 设置单个发送消息的过期时间
创建配置文件
/**
* @author: mingan.xie
* @since: 2021/3/22
* @history: 1.2021/3/22 created by xma
*/
@Configuration
public class RabbitMQConfigTTL {
// 1: 声明交换机
@Bean
public TopicExchange ttlTopicExchange(){
return new TopicExchange("ttl_topic_order_product");
}
@Bean
public Queue ttlMessageTopicduanxinQueue(){
return new Queue("ttl.message.duanxin.topic.queue", true);
}
@Bean
public Binding ttlMessageTopicsmsBinding(){
return BindingBuilder.bind(ttlMessageTopicduanxinQueue()).to(ttlTopicExchange()).with("ttl.message");
}
}
创建生产者
@Component
public class ProductFanout {
@Resource
private RabbitTemplate rabbitTemplate;
public void makerOrderTopicTtlMessage(){
String exchangeName = "ttl_topic_order_product";
// 参数1: 交换机名称
// 参数2: direct 和 topic 模式下的路由key / 无交换机模式下的路由名称
String routingKey = "ttl.message";
// 参数3: 消息体
String orderId = UUID.randomUUID().toString();
MessagePostProcessor messagePostProcessor = message -> {
// 设置过期时间
message.getMessageProperties().setExpiration("5000");
message.getMessageProperties().setContentEncoding("UTF-8");
return message;
};
rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId, messagePostProcessor);
System.out.println("路由key:" + routingKey);
}
}
调用测试类
@SpringBootTest
class SpringBootRabbitmqProducerApplicationTests {
@Resource
private ProductFanout productFanout;
@Test
void contextLoads5() {
productFanout.makerOrderTopicTtlMessage();
}
}
6. 死信队列
由于某些原因导致队列中某些消息无法被消费,这些消息就会被放到死信对类中
产生死信的几种方式:
消息被拒绝
消息TTL过期
队列达到最大长度
6.1 创建死信队列
/**
* @author: mingan.xie
* @since: 2021/3/22
* @history: 1.2021/3/22 created by xma
*/
@Configuration
public class RabbitMQConfigDead {
// 1: 声明交换机
@Bean
public TopicExchange deadTopicExchange(){
return new TopicExchange("dead_topic_order_product");
}
// 2: 声明队列
// durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
// exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
// autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
@Bean
public Queue deadTopicduanxinQueue(){
return new Queue("dead.duanxin.topic.queue", true);
}
// 3: 绑定对用关系
@Bean
public Binding deadTopicsmsBinding(){
return BindingBuilder.bind(deadTopicduanxinQueue()).to(deadTopicExchange()).with("dead");
}
}
6.2 创建普通队列并绑定死信队列
/**
* @author: mingan.xie
* @since: 2021/3/22
* @history: 1.2021/3/22 created by xma
*/
@Configuration
public class RabbitMQConfigTTL {
// 1: 声明交换机
@Bean
public TopicExchange ttlTopicExchange(){
return new TopicExchange("ttl_topic_order_product");
}
// 2: 声明队列
// durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
// exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
// autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
@Bean
public Queue ttlTopicduanxinQueue(){
HashMap<String, Object> args = new HashMap<>();
// 给队列设置消息过期时间:毫秒值
args.put("x-message-ttl", 5000);
// 设置队列最大长度
args.put("x-max-length", 5);
// 设置死信队列交换机名称
// 当消息在一个队列中变成死信后,它能就发送到另一个交换机中,这个交换机就是DLX,绑定DLX的队列被称之为死信队列
// 编程死信队列的原因:消息被拒绝,消息过期,队列达到最大长度
args.put("x-dead-letter-exchange", "dead_topic_order_product");
// 设置死信队列路由key
args.put("x-dead-letter-routing-key", "dead");
return new Queue("ttl.duanxin.topic.queue", true, false, false, args);
}
// 3: 绑定对用关系
@Bean
public Binding ttlTopicsmsBinding(){
return BindingBuilder.bind(ttlTopicduanxinQueue()).to(ttlTopicExchange()).with("ttl");
}
}
6.3 创建生产者
@Component
public class ProductFanout {
@Resource
private RabbitTemplate rabbitTemplate;
public void makerOrderTopicTtl(){
// 参数1: 交换机名称
String exchangeName = "ttl_topic_order_product";
// 参数2: direct 和 topic 模式下的路由key / 无交换机模式下的路由名称
String routingKey = "ttl";
// 参数3: 消息体
String orderId = UUID.randomUUID().toString();
rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId);
System.out.println("路由key:" + routingKey);
}
}
6.4 调用测试类
@SpringBootTest
class SpringBootRabbitmqProducerApplicationTests {
@Resource
private ProductFanout productFanout;
@Test
void contextLoads4() {
for (int i = 0; i < 10; i++) {
productFanout.makerOrderTopicTtl();
}
}
}
设置类队列的最大长度为5,超过队列长度的消息都会被放到死信队列中
设置类队列消息过期时间为5秒,5秒过后消息未被消费,也会被放到死信队列中
7. 总结
-
- 使用IDEA打开 spring-boot-rabbitmq-producer文件即可