记得上篇文章我写了关于路由消息模型,这篇文章咱们讲一下RabbitMQ 发布订阅消息模型,也是上次那个概念。消息的发送者(sender)通过 交换机给消息队列分发消息,消息的消费者就监听和消费消息队列里面的消息。
这张图片就诠释了声明是发布订阅消息模型、相对于路由消息模型它就不是通过不同路由给相对应的消息队列分发消息了,发布订阅模式,就是给绑定了的消息队列都发消息。
就像p给x发了一条消息:hello world,x 就会将 hello world这条消息,分发给它绑定了的所有的消息队列,队列a会有,队列b也会有。
如何实现呢,
还是创建一个父工程,父工程下面有两个子工程,一个是消息的提供者,一个消息的消费者。
首先第一步在咱们的父工程的pom.xml文件添加依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<version>2.1.4.RELEASE</version>
<artifactId>spring-boot-starter-parent</artifactId>
</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-amqp</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
紧接着是消息提供者(mq-provider)的配置文件 application.yml:
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
virtual-host: /
如何写配置类(PublishRabbitMQConfig),用于声明交换机和消息队列,并让交换机和所有的队列进行绑定。
package com.shenwang.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* rabbitmq发布订阅模式
* @author shenwang
* @version 1.0
*/
@Configuration
public class PublishRabbitConfig {
/**
* 扇型交换器
* @return
*/
@Bean
public FanoutExchange fanoutExchange(){
return new FanoutExchange("myFanoutExchange");
}
/**
* 队列1
* @return
*/
@Bean
public Queue queue1(){
return new Queue("fanoutMsgQueue1");
}
/**
* 队列2
* @return
*/
@Bean
public Queue queue2(){
return new Queue("fanoutMsgQueue2");
}
/**
* 绑定第一个队列
* @return
*/
@Bean
public Binding binding1(){
return BindingBuilder.bind(queue1()).to(fanoutExchange());
}
/**
* 绑定第二个队列
* @return
*/
@Bean
public Binding binding2(){
return BindingBuilder.bind(queue2()).to(fanoutExchange());
}
}
再写一个Controller类去发送咱们的消息
/**
* @author shenwang
* @version 1.0
*/
@RestController
@RequestMapping("/mq")
public class RabbitmqController {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 测试 发布订阅模式
* @return
*/
@GetMapping("/fanout")
public String fanoutSend(){
String message="测试fanout";
rabbitTemplate.convertAndSend("myFanoutExchange",null,message);
return "success!!!";
}
}
这样咱们的消息提供者就写完啦,赶紧去测试一下吧。
访问:localhost:8080/mq/fanout
紧接着去访问:http://localhost:15672/ 进入咱们的可视化客户端 去看咱们的消息吧
可以看到咱们在配置类里面声明的消息队列都出来啦,点击去看一下吧。
这两个队列里都有这个消息窝~
到这里咱们消息的提供者就写完啦,接下来去写咱们的一个消费者
mq-comsumer它的application.yml其实也不用写,因为它默认的账号就是guest,虚拟地址是 /
但是有需要的小伙伴可以自己去配一下,我这只配了一个端口为了防止两个项目端口冲突。如果非要写的话,和咱们消息提供者的信息对应上就好啦
消息的监听和消费无非也就两个注解,@RabbitHandler,@RabbitListener直接上代码,一秒懂窝
/**
* 发布订阅消息模型 监听消费
* @author shenwang
* @version 1.0
*/
@Component
public class PublishReceiver {
/**
* 监听和消费 fanoutMsgQueue1的消息
* @param message
*/
@RabbitHandler
@RabbitListener(queues = "fanoutMsgQueue1")
public void receiverFanoutMsgQueue1(String message){
System.out.println("---------------fanoutMsgQueue1---------------");
System.out.println(message);
}
/**
* 监听和消费 fanoutMsgQueue2的消息
* @param message
*/
@RabbitHandler
@RabbitListener(queues = "fanoutMsgQueue2")
public void receiverFanoutMsgQueue2(String message){
System.out.println("---------------fanoutMsgQueue2---------------");
System.out.println(message);
}
}
这里代码的意思是监听和消费这两个队列中的消息。
启动一下消费者看一下控制台就知道啦:
看到啦,两个消息队列都是一样的消息,怎么样,应该悟了什么是发布订阅消息模型了吧
总结一下:就交换机将提供者发来的消息 分发给它绑定了的每一个消息队列。