RabbitMQ三种模式

1 直接模式(Direct

1.1  什么是 Direct 模式
我们需要将消息发给唯一一个节点时使用这种模式,这是最简单的一种形式。
任何发送到 Direct Exchange 的消息都会被转发到 RouteKey 中指定的 Queue
1. 一般情况可以使用 rabbitMQ 自带的 Exchange ”"( Exchange 的名字为空字符串,下
文称其为 default Exchange)
2. 这种模式下不需要将 Exchange 进行任何绑定 (binding) 操作
3. 消息传递时需要一个 “RouteKey” ,可以简单的理解为要发送到的队列名字。
4. 如果 vhost 中不存在 RouteKey 中指定的队列名,则该消息会被抛弃。

1.2 创建队列
做下面的例子前,我们先建立一个叫 nbpuls 的队列。(前提运行docker下的rabbitmq)
Durability :是否做持久化 Durable (持久) transient (临时)
Auto delete : 是否自动删除

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

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)运行测试这个方法 

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

 .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)运行启动类,可以在控制台看到刚才发送的消息

  已经成功输出

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

5 测试
开启多个消费者工程,测试运行消息生产者工程,会发现只有一个消费者工程可以接收
到消息。
如何在 IDEA 中多次启动同一个程序呢?
1 )选择 IDEA右上角的类名称按钮 
(2)选择 Edit Configurations
(3)在弹出窗口中取消单例模式 ,点击 OK

 

(4)每次运行前修改 application.yml ,指定不同的端口 ,修改三次端口号,运行三次启动类,相当于有三个消费者接受消息,最后运行生产者测试方法:
 测试运行消息生产者工程,会发现只有一个消费者工程可以接收 到消息。

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

2   分列模式(Fanout

   1 什么是分列(Fanout)模式

当我们需要将消息一次发给多个队列时,需要使用这种模式。如下图:
任何发送到 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

 

 点击boss添加绑定 team1和team2 

绑定后效果如下:

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","","分裂模式测试");
    }
}

 启动

启动后结果如下

 

3 主题模式(Topic

.1 什么是主题模式
任何发送到 Topic Exchange 的消息都会被转发到所有关心 RouteKey 中指定话题的 Queue
如上图所示
此类交换器使得来自不同的源头的消息可以到达一个对列,其实说的更明白一点就是模
糊匹配的意思,例如:上图中红色对列的 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

  1.浏览器rabbitmq上创建主题模式交换

创建成功topicmodel后

 

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

就行绑定team2

 

 

一共就绑定这三个。

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","主题模式测试");
    }
}

结果:

测试二 启动sendMsg3方法  

 启动:

结果:

测试三启动sendMsg3方法  

启动:

 结果:

猜你喜欢

转载自blog.csdn.net/qq_39772439/article/details/121250442