1 直接模式(Direct)


1.1  什么是 Direct 模式


我们需要将消息发给唯一一个节点时使用这种模式,这是最简单的一种形式。




Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_直接模式


任何发送到 Direct Exchange 的消息都会被转发到 RouteKey 中指定的 Queue 。


1. 一般情况可以使用 rabbitMQ 自带的 Exchange : ”"( 该 Exchange 的名字为空字符串,下


文称其为 default Exchange) 。


2. 这种模式下不需要将 Exchange 进行任何绑定 (binding) 操作


3. 消息传递时需要一个 “RouteKey” ,可以简单的理解为要发送到的队列名字。


4. 如果 vhost 中不存在 RouteKey 中指定的队列名,则该消息会被抛弃。


1.2 创建队列


做下面的例子前,我们先建立一个叫 nbpuls 的队列。(前提运行docker下的rabbitmq)


Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_Test_02


Durability :是否做持久化 Durable (持久) transient (临时)


Auto delete : 是否自动删除


然后点击Add queue 添加,就会发现nbpuls已经添加成功 


Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_rabbitmq_03


3 代码实现 - 消息生产者


( 1 )创建工程 rabbitmq_demo ,引入 amqp 起步依赖 , pom.xml 如下:


<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            <version>2.0.1.RELEASE</version>
        </dependency>
    </dependencies>


(2)编写配置文件 application.yml


server:
  port: 8002
spring:
  rabbitmq:
    host: 192.168.63.131


(3)编写启动类


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RabbitApplication {

    public static void main(String[] args) {
        SpringApplication.run( RabbitApplication.class, args);
    }
}


(4)编写测试类


import com.zhao588.rabbit.RabbitApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = RabbitApplication.class)
public class ProductTest
{

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /*
    * 直接模式
    * */
    @Test
    public void sendMsg1(){

        rabbitTemplate.convertAndSend("nbplus","直接模式测试");
    }
}

(5)运行测试这个方法 

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_直接模式_04

 (6)运行完毕之后查看浏览器,已经接收到发放发出的消息

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_spring_05

.4 代码实现-消息消费者


( 1 )编写消息消费者类


import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@RabbitListener(queues = "nbplus")
public class Custmer1
{

     @RabbitHandler
    public void getMsg(String msg){
        System.out.println("直接模式输出:"+msg);
    } 
}


(2)运行启动类,可以在控制台看到刚才发送的消息


Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_rabbitmq_06


  已经成功输出

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_直接模式_07

浏览器rabbitmq 消息数量归零,说明已经被消费。 

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_直接模式_08

 


5 测试


开启多个消费者工程,测试运行消息生产者工程,会发现只有一个消费者工程可以接收


到消息。


如何在 IDEA 中多次启动同一个程序呢?


( 1 )选择 IDEA右上角的类名称按钮 

(2)选择 Edit Configurations


(3)在弹出窗口中取消单例模式 ,点击 OK


Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_spring_09

 

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_直接模式_10

 


(4)每次运行前修改 application.yml ,指定不同的端口 ,修改三次端口号,运行三次启动类,相当于有三个消费者接受消息,最后运行生产者测试方法:


Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_rabbitmq_11


 


 测试运行消息生产者工程,会发现只有一个消费者工程可以接收 到消息。


 

消费者工程可以接收 到消息。第三次运行也和第二种情况一样,说明这里遵循了负载均衡的规律。

2   分列模式(Fanout)

   1 什么是分列(Fanout)模式


当我们需要将消息一次发给多个队列时,需要使用这种模式。如下图:


Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_Test_12


任何发送到 Fanout Exchange 的消息都会被转发到与该 Exchange 绑定 (Binding) 的所有


Queue 上。


1. 可以理解为路由表的模式


2. 这种模式不需要 RouteKey


3. 这种模式需要提前将 Exchange 与 Queue 进行绑定,一个 Exchange 可以绑定多个


Queue ,一个 Queue 可以同多个 Exchange 进行绑定。


4. 如果接受到消息的 Exchange 没有与任何 Queue 绑定,则消息会被抛弃。


 2  交换器绑定队列


( 1 )在 queue 中添加队列 team1 和 team2


(2)新建交换器 boss

 

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_直接模式_13

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_Test_14

 点击boss添加绑定 team1和team2 

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_rabbitmq_15

 

绑定后效果如下:

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_Test_16

 


4 代码实现 - 消息消费者


创建消息监听类,用于监听 team1 的消息


import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@RabbitListener(queues = "team1")
public class Custmer1
{

    @RabbitHandler
    public void getMsg(String msg){
        System.out.println("team1分裂模式输出:"+msg);
    }
}

创建消息监听类,用于监听team2的消息

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@RabbitListener(queues = "team2")
public class Custmer2
{
    @RabbitHandler
    public void getMsg(String msg){
        System.out.println("team2分裂模式输出:"+msg);
    }
}


5 测试


启动消费者工程,发送消息测试


import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = RabbitApplication.class)
public class ProductTest
{

    @Autowired
    private RabbitTemplate rabbitTemplate;
 
    /*
    * 分裂模式
    * */
     @Test
    public void sendMsg2(){

        rabbitTemplate.convertAndSend("boss","","分裂模式测试");
    }
}

 启动

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_Test_17

启动后结果如下

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_直接模式_18

 

3 主题模式(Topic)


.1 什么是主题模式


任何发送到 Topic Exchange 的消息都会被转发到所有关心 RouteKey 中指定话题的 Queue



Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_spring_19


如上图所示


此类交换器使得来自不同的源头的消息可以到达一个对列,其实说的更明白一点就是模


糊匹配的意思,例如:上图中红色对列的 routekey 为 usa.# , # 代表匹配任意字符,但是


要想消息能到达此对列, usa. 必须匹配后面的 # 好可以随意。图中 usa.news


usa.weather, 都能找到红色队列,符号 # 匹配一个或多个词,符号 * 匹配不多不少一个


词。因此 usa.# 能够匹配到 usa.news.XXX ,但是 usa.* 只会匹配到 usa.XXX 。


注:


交换器说到底是一个名称与队列绑定的列表。当消息发布到交换器时,实际上是由你所


连接的信道,将消息路由键同交换器上绑定的列表进行比较,最后路由消息。


任何发送到 Topic Exchange 的消息都会被转发到所有关心 RouteKey 中指定话题的


Queue


1. 这种模式较为复杂,简单来说,就是每个队列都有其关心的主题,所有的消息都带有一


个 “ 标题 ”(RouteKey) , Exchange 会将消息转发到所有关注主题能与 RouteKey 模糊匹配的


队列。


2. 这种模式需要 RouteKey ,也许要提前绑定 Exchange 与 Queue 。


3. 在进行绑定时,要提供一个该队列关心的主题,如 “#.log.#” 表示该队列关心所有涉及


log 的消息 ( 一个 RouteKey 为 ”MQ.log.error” 的消息会被转发到该队列 ) 。


4.“#” 表示 0 个或若干个关键字, “ 表示一个关键字。如 “log. ” 能与 “log.warn” 匹配,无法


与 “log.warn.timeout” 匹配;但是 “log.#” 能与上述两者匹配。


5. 同样,如果 Exchange 没有发现能够与 RouteKey 匹配的 Queue ,则会抛弃此消息


 


2 创建队列与绑定


( 1 )新建一个交换器 ,类型选择 top


Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_Test_20

创建成功topicmodel后

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_直接模式_21

 

 点击topicmodel,绑定队列team1 这个里的Rounting key可 随意写,不过得记住,后面用。

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_spring_22

就行绑定team2

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_直接模式_23

  

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_spring_24

一共就绑定这三个。


3 代码实现


编写测试类方法:先启动启动类


  测试一 启动sendMsg3方法  


import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = RabbitApplication.class)
public class ProductTest
{

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /*
    * 主题模式测试
    * */
    @Test
    public void sendMsg3(){

        rabbitTemplate.convertAndSend("topicmodel","good.abc","主题模式测试");
    }
}

结果:

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_spring_25

测试二 启动sendMsg3方法  

 启动:

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_spring_26

结果:

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_spring_27

 

测试三启动sendMsg3方法  

启动:

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_Test_28

 结果:

Springboot Rabbitmq配置文件绑定多个队列 rabbitmq direct多个队列_spring_29