RabbitMQ的4种广播类型与DEMO

RabbitMQ的4种广播类型与DEMO

Posted by John Doe on 2021-03-01
Words 1.5k and Reading Time 6 Minutes
Viewed Times

rabbitmq管理界面

可见我的上篇文章介绍的rabbitMQ基础与docker安装rabbitMQ management
网址输入:http://127.0.0.1:15672/
登录名&密码:guest
rabbitmq管理界面

1.直接模式Direct

直接模式介绍

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

直接模式demo代码

添加队列
添加队列

pom.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>

DirectCustomer.Class

1
2
3
4
5
6
7
8
9
@Component
@RabbitListener(queues = "rabbitMQ-direct")
public class DirectCustomer {

@RabbitHandler
public void getMsg(String msg){
System.out.println("直接模式消费消息"+ msg);
}
}

application.yml:
1
2
3
spring: 
rabbitmq:
host: 127.0.0.1

appliction.properties:

1
spring.rabbitmq.host=127.0.0.1

Test:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.example.rabbitmq;

import org.junit.jupiter.api.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 = RabbitmqApplication.class)
class RabbitmqApplicationTests {

@Test
void contextLoads() {
}


@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void testSend(){
rabbitTemplate.convertAndSend("rabbitMQ-direct","我要红包");
}
}

运行项目观察控制台
运行项目观察控制台

2.headers模式

headers:与 direct 类似,只是性能很差,此类型几乎用不到。

3.fanout分发模式

fanout分发模式介绍

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

分发模式demo代码

管理界面操作:
运行项目观察控制台
运行项目观察控制台
运行项目观察控制台
运行项目观察控制台
运行项目观察控制台
Test:

1
2
3
4
@Test
public void testSend2(){
rabbitTemplate.convertAndSend("rabbitmq-gzx","","分裂模式");
}

消费者代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.example.rabbitmq;

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

@Component
@RabbitListener(queues = "rabbitMQ-fanout1")
public class FanoutCustomer1 {

@RabbitHandler
public void getMsg(String msg){
System.out.println("分发模式1消费消息"+ msg);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.example.rabbitmq;

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

@Component
@RabbitListener(queues = "rabbitMQ-fanout2")
public class FanoutCustomer2 {

@RabbitHandler
public void getMsg(String msg){
System.out.println("分发模式2消费消息"+ msg);
}
}

启动测试类发送消息,观察控制台结果
分发模式

4.topic主题模式

主题模式介绍

任何发送到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,则会抛弃此消息

主题模式demo代码

管理界面操作:
主题模式
主题模式

Test:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void testTopicSend1(){
rabbitTemplate.convertAndSend("rabbitmq-topic","china.news","主题模式消息1");
}

@Test
public void testTopicSend2(){
rabbitTemplate.convertAndSend("rabbitmq-topic","chengdu.weather","主题模式消息2");
}

@Test
public void testTopicSend3(){
rabbitTemplate.convertAndSend("rabbitmq-topic","usa.news","主题模式消息3");
}

查看运行结果:
主题模式


This is copyright.

...

...

00:00
00:00