交换机属性-持久化和自动删除
- 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服务器,再重新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是不一样的,所以消息经由备份交换机进入了备份队列。
登录rabbitmq后台可以看到,消息并没有进入正常队列,因为生产者发送消息时制度的路由key跟正常交换机和正常队列绑定的路由key是不一样的,所以消息经由备份交换机进入了备份队列。

 此时启动消费者,监听备份队列,我们呢发现,消费者从备份队列中读取到了消息。验证了上边说的,消息进入了备份队列。
 



















