交换机属性-持久化和自动删除
- 1、交换机常用属性
- 2、交换机(Exchange)的持久化属性
- 2.1、RabbitConfig配置类(关键代码)
- 2.2、发送消息
- 2.3、启动类
- 2.4、application.yml配置文件
- 2.5、pom.xml配置文件
- 2.6、测试
- 3、交换机(Exchange)的自动删除属性
- 3.1、RabbitConfig配置类(关键代码)
- 3.2、发送消息
- 3.3、启动类
- 3.4、application.yml配置文件
- 3.5、pom.xml配置文件
- 3.6、测试
- 4、备用交换机
- 4.1、使用场景
- 4.2、代码还原场景
- 4.2.1、生产者
- 4.2.1.1、RabbitConfig配置类(关键)
- 4.2.1.2、application.yml
- 4.2.1.3、发送消息
- 4.2.1.4、启动类
- 4.2.1.5、配置文件pom.xml
- 4.2.2、消费者
- 4.2.2.1、监听类(监听消息发送)
- 4.2.2.2、启动类
- 4.2.2.3、配置文件application.yml
- 4.2.2.4、配置文件pom.xml
- 4.3、测试
1、交换机常用属性
1、Name:交换机名称;就是一个字符串
2、Type:交换机类型,direct, topic, fanout, headers四种
3、Durability:持久化,声明交换机是否持久化,代表交换机在服务器重启后是否还存在;
4、Auto delete:是否自动删除,曾经有队列绑定到该交换机,后来解绑了,那就会自动删除该交换机;
5、Internal:内部使用的,如果是yes,客户端无法直接发消息到此交换机,它只能用于交换机与交换机的绑定。
6、Arguments:只有一个取值alternate-exchange,表示备用交换机;
2、交换机(Exchange)的持久化属性
交换机默认是持久化的,即创建后重启rabbitmq服务器交换机也不会丢失。
2.1、RabbitConfig配置类(关键代码)
package com.power.config;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitConfig {
@Value("${my.exchangeName}")
private String exchangeName;
@Value("${my.queueName}")
private String queueName;
//创建交换机
@Bean
public DirectExchange directExchange(){
return ExchangeBuilder //交换机默认是持久化的
.directExchange(exchangeName)
.durable(false) //durable值默认是true,如果此处设置为false,那么Rabbitmq服务器重启后交换机就不会持久化,会自动删除
.build();
}
//创建队列
@Bean
public Queue queue(){
return QueueBuilder.durable(queueName).build();
}
@Bean
public Binding binding(DirectExchange exchangeName,Queue queueName){
return BindingBuilder.bind(queueName).to(exchangeName).with("info");
}
}
2.2、发送消息
package com.power.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
@Service
@Slf4j
public class MessageService {
@Resource
private RabbitTemplate rabbitTemplate;
@Value("${my.exchangeName}")
private String exchangeName;
@Bean
public void sendMsg(){
Message message = MessageBuilder.withBody("hello world".getBytes()).build();
rabbitTemplate.convertAndSend(exchangeName,"info",message);
log.info("消息发送完毕,发送时间是:"+new Date());
}
}
2.3、启动类
package com.power;
import com.power.service.MessageService;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.annotation.Resource;
@SpringBootApplication
public class Application implements ApplicationRunner {
@Resource
private MessageService messageService;
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
@Override
public void run(ApplicationArguments args) throws Exception {
messageService.sendMsg();
}
}
2.4、application.yml配置文件
server:
port: 8080
spring:
application:
name: rabbit_10_exchange_properties01
rabbitmq:
host: 你的服务器IP
port: 5672
username: 你的账号
password: 你的密码
virtual-host: power
my:
exchangeName: exchange.properties.01
queueName: queue.properties.01
2.5、pom.xml配置文件
<?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.power</groupId>
<artifactId>rabbit_10_exchange_properties01</artifactId>
<version>1.0-SNAPSHOT</version>
<name>rabbit_10_exchange_properties01</name>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.13</version>
<relativePath/>
</parent>
<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>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.6、测试
先启动服务,然后登录rabbitmq服务器查看,发现新创建的交换机并没有被持久化。
关闭rabbitmq服务器,再重新rabbitmq
登录rabbitmq后台,查看刚刚创建的交换机不见了
3、交换机(Exchange)的自动删除属性
如果解绑了队列和交换机,即没有队列和交换机进行绑定时,默认情况下,交换机不会自动删除的;
当设置了该属性的时候,我们解绑队列和交换机的话,交换机会自动删除的。
3.1、RabbitConfig配置类(关键代码)
package com.power.config;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitConfig {
@Value("${my.exchangeName}")
private String exchangeName;
@Value("${my.queueName}")
private String queueName;
//创建交换机
@Bean
public DirectExchange directExchange(){
return ExchangeBuilder //交换机默认不是自动删除的。即如果队列和交换机解绑,默认情况下不会自动删除交换机
.directExchange(exchangeName)
.autoDelete()//不设该值是默认不自动删除,设完后自动删除。
.build();
}
//创建队列
@Bean
public Queue queue(){
return QueueBuilder.durable(queueName).build();
}
@Bean
public Binding binding(DirectExchange exchangeName,Queue queueName){
return BindingBuilder.bind(queueName).to(exchangeName).with("info");
}
}
3.2、发送消息
代码同上
3.3、启动类
代码同上
3.4、application.yml配置文件
server:
port: 8080
spring:
application:
name: rabbit_10_exchange_properties01
rabbitmq:
host: 你的服务器IP
port: 5672
username: 你的账号
password: 你的密码
virtual-host: power
my:
exchangeName: exchange.properties.02
queueName: queue.properties.02
3.5、pom.xml配置文件
同上
3.6、测试
先启动服务,然后登录rabbitmq服务器查看,发现新创建的交换机自动删除属性是true。
进入该交换机,尝试解绑交换机和队列
解绑完成后,回到交换机列表页面,发现交换机exchange.properties.02自动删除了
4、备用交换机
4.1、使用场景
当消息经过交换器准备路由给队列的时候,发现没有对应的队列可以投递信息,在rabbitmq中会默认丢弃消息,如果我们想要监测哪些消息被投递到没有对应的队列,我们可以用备用交换机来实现,可以接收备用交换机的消息,然后记录日志或发送报警信息。
说明:
1、生产者发送消息给正常交换机(交换机类型为直连);
2、正常情况下,直连交换机接收到消息,根据生产者发送时的路由key将消息发送至正常队列;
3、正常队列接收到消息;
4、如果生产者发送消息时的路由key为info111,而正常交换机和正常队列绑定的路由key是info,那么此时的消息不会进入正常队列,而是会进入备份交换机里;
5、备份交换机接收到消息,交换机类型是扇形,会发送给备份队列;
6、消费者监听备份队列,如果备份队列有值,说明生产者发送的消息没有正常传递,此时消费者一旦监听到备份队列里头有值,就应该通过邮件,短信、记录日志等方式提醒系统运维人员。
4.2、代码还原场景
4.2.1、生产者
4.2.1.1、RabbitConfig配置类(关键)
package com.power.config;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitConfig {
@Value("${my.exchangeNormalName}")
private String exchangeNormalName;
@Value("${my.exchangeAlternateName}")
private String exchangeAlternateName;
@Value("${my.queueNormalName}")
private String queueNormalName;
@Value("${my.queueAlternateName}")
private String queueAlternateName;
//创建正常交换机
@Bean
public DirectExchange directExchange(){
return ExchangeBuilder
.directExchange(exchangeNormalName)
.alternate(exchangeAlternateName) //设置备用交换机
.build();
}
//创建正常队列
@Bean
public Queue queueNormal(){
return QueueBuilder.durable(queueNormalName).build();
}
//正常交换机和正常队列绑定
@Bean
public Binding binding(DirectExchange directExchange,Queue queueNormal){
return BindingBuilder.bind(queueNormal).to(directExchange).with("info");
}
//创建备份交换机
@Bean
public FanoutExchange fanoutExchange(){
return ExchangeBuilder.fanoutExchange(exchangeAlternateName).build();
}
//创建备份队列
@Bean
public Queue queueAlternate(){
return QueueBuilder.durable(queueAlternateName).build();
}
//绑定备份交换机和备份队列
@Bean
public Binding bindingAlternate(FanoutExchange fanoutExchange,Queue queueAlternate){
return BindingBuilder.bind(queueAlternate).to(fanoutExchange);
}
}
4.2.1.2、application.yml
server:
port: 8080
spring:
application:
name: rabbit_10_exchange03_alternate
rabbitmq:
host: 你的服务器IP
port: 5672
username: 你的账号
password: 你的密码
virtual-host: power
my:
exchangeNormalName: exchange.normal.02 #正常交换机
exchangeAlternateName: exchange.alternate.02 #备份交换机
queueNormalName: queue.normal.02 #正常队列
queueAlternateName: queue.alternate.02 #备份队列
4.2.1.3、发送消息
为了测试消息发送失败的场景,此处发送时的路由key设置为错的
package com.power.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
@Service
@Slf4j
public class SendMessageService {
@Resource
private RabbitTemplate rabbitTemplate;
@Value("${my.exchangeNormalName}")
private String exchangeNormalName;
@Bean
public void sendMsg(){
Message message = MessageBuilder.withBody("hello world".getBytes()).build();
rabbitTemplate.convertAndSend(exchangeNormalName,"info111",message);
log.info("向正常交换机消息发送完毕,发送时间是:{}",new Date());
}
}
4.2.1.4、启动类
package com.power;
import com.power.service.SendMessageService;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.annotation.Resource;
@SpringBootApplication
public class Application implements ApplicationRunner {
@Resource
private SendMessageService messageService;
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
@Override
public void run(ApplicationArguments args) throws Exception {
messageService.sendMsg();
}
}
4.2.1.5、配置文件pom.xml
<?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.power</groupId>
<artifactId>rabbit_10_exchange03_alternate</artifactId>
<version>1.0-SNAPSHOT</version>
<name>rabbit_10_exchange03_alternate</name>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.13</version>
<relativePath/>
</parent>
<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>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4.2.2、消费者
4.2.2.1、监听类(监听消息发送)
package com.power.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
@Slf4j
public class ReceiveMessageService {
@RabbitListener(queues={"queue.alternate.02"})
public void getMsg(Message message){
byte[] body = message.getBody();
String msg = new String(body);
log.info("监听到备份队列的消息:"+msg+",接收的时间是:"+new Date());
}
}
4.2.2.2、启动类
package com.power;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
4.2.2.3、配置文件application.yml
server:
port: 9090
spring:
application:
name: rabbit_10_exchange04_alternate_getMsg
rabbitmq:
host: 你的rabbitmq服务器IP
port: 5672
username: 你的账号
password: 你的密码
virtual-host: power
4.2.2.4、配置文件pom.xml
<?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.power</groupId>
<artifactId>rabbit_10_exchange04_alternate_getMsg</artifactId>
<version>1.0-SNAPSHOT</version>
<name>rabbit_10_exchange04_alternate_getMsg</name>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.13</version>
<relativePath/>
</parent>
<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>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4.3、测试
先启动生产者发送消息:
登录rabbitmq后台可以看到,消息并没有进入正常队列,因为生产者发送消息时制度的路由key跟正常交换机和正常队列绑定的路由key是不一样的,所以消息经由备份交换机进入了备份队列。
此时启动消费者,监听备份队列,我们呢发现,消费者从备份队列中读取到了消息。验证了上边说的,消息进入了备份队列。