新建一个springboot的项目,引入RabbitMQ的pom.xml依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
yml配置
spring:
rabbitmq:
host: 192.168.88.134
# port: 5672
# username: guest
# password: guest
#端口默认就是5672可以不写
#用户名和密码没改默认就是guest可以不写
1、点对点,简单的生产者消费者
我们需要将消息发给唯一一个节点时使用这种模式,这是最简单的一种形式。
P:消息的生产者
C:消息的消费者
红色:队列
生产者将消息发送到队列,消费者从队列中获取消息。
我们先建立一个叫testJD的队列。
Durability:是否做持久化 Durable(持久) transient(临时)
Auto delete : 是否自动删除
然后编写测试类
@Autowired
private RabbitTemplate rabbitTemplate;
//简单生产者消费者、点对点
@Test
public void contextLoads() {
rabbitTemplate.convertAndSend("testJD","RabbitMQ:发送消息:简单队列(直接模式)");
}
运行测试类
编写消息消费者类(监听testJD)
@Component //组件
@RabbitListener(queues = "testJD")
public class Consumer1 {
@RabbitHandler
public void showMessage(String message){
System.out.println("Consumer1接收到消息:"+message);
}
}
运行启动类,可以在控制台看到刚才发送的消息
2、工作模式(work)
工作模式和上边的模式差不多,只是对于当前的队列多了一个消费者:
一个生产者、2个消费者。
一个消息只能被一个消费者获取。
如下图所示:
还是这个项目新增一个消费者Consumer2
@Component //组件
@RabbitListener(queues = "testJD")
public class Consumer2 {
@RabbitHandler
public void showMessage(String message){
System.out.println("Consumer2接收到消息:"+message);
}
}
新增一个测试方法
//工作模式 work
/**
* 一个生产者、2个消费者。
* 一个消息只能被一个消费者获取。
*/
@Test
public void testWork() {
rabbitTemplate.convertAndSend("testJD","RabbitMQ:Work模式");
}
先重启项目再运行这个测试方法控制台打印如下:
多运行几次测试方法在看看控制台打印结果:
会发现他是轮询得到的
3、发布/订阅模式Publish/Subscribe
解读:
1、1个生产者,多个消费者
2、每一个消费者都有自己的一个队列
3、生产者没有将消息直接发送到队列,而是发送到了交换机
4、每个队列都要绑定到交换机
5、生产者发送的消息,经过交换机,到达队列,实现,一个消息被多个消费者获取的目的
注意:一个消费者队列可以有多个消费者实例,只有其中一个消费者实例会消费
首先创建一个交换机test:
再创建一个消息队列testDY
双击你刚刚创建的转换机test将两个队列与之进行绑定
绑定成功之后如下:
还是这个项目
添加一个测试方法:
//发布/订阅模式Publish/Subscribe
/**
* 解读:
* 1、1个生产者,多个消费者
* 2、每一个消费者都有自己的一个队列
* 3、生产者没有将消息直接发送到队列,而是发送到了交换机
* 4、每个队列都要绑定到交换机
* 5、生产者发送的消息,经过交换机,到达队列,实现,一个消息被多个消费者获取的目的
* 注意:一个消费者队列可以有多个消费者实例,只有其中一个消费者实例会消费
*/
@Test
public void testFanout() {
rabbitTemplate.convertAndSend("test","","RabbitMQ:发布/订阅模式Publish/direct");
}
再新增一个消费者Consumer3 (监听testDY):
@Component
@RabbitListener(queues = "testDY")
public class Consumer3 {
@RabbitHandler
public void showMessage(String message){
System.out.println("testDY接收到消息:"+message);
}
}
先重启项目再运行这个测试方法控制台打印如下(Consumer1是与队列testJD进行绑定的):
4、routing路由模式
交换机绑定的路由key和队列绑定的一样时,才发送。
根据发送消息的routingKey来进行匹配(不支持占位符匹配)
一个消息只能被一个相匹配的消息队列获取
新建一个交换机luyou(修改类型为direct)
将队列testJD与testDY与交换机luyou进行绑定
修改testJD的Routing key 的值为message.log
将testDY的Routing key 的值为error.log,绑定成功后效果图如下:
还是这个项目
添加一个测试方法:
//routing路由模式
//交换机的类型为direct
/**
* 根据发送消息的routingKey来进行匹配(不支持占位符匹配)
* 一个消息只能被一个相匹配的消息队列获取
*/
@Test
public void testRouting() {
rabbitTemplate.convertAndSend("luyou","error.log","RabbitMQ:使用路由模式发送了消息:error.log");
}
运行测试方法控制台打印如下:
5、topic主题模式
此类交换器使得来自不同的源头的消息可以到达一个对列
其实说白了就是根据消息的Routing key来进行模糊匹配,一个消息的Routing key如果有多个消息队列匹配那就能被相匹配的接收
新建一个交换机zhqTopic(注意:类型一定要改为topic)
新建一个消息队列testTopic(现在一共有3个消息队列)
将这三个队列与交换机zhqTopic进行绑定并设置Routing key的值
注意:符号 # 匹配一个或多个词,符号 * 匹配不多不少一个
词。因此 usa.# 能够匹配到 usa.news.xxx,但是 usa.* 只会匹配到 usa.xxx
绑定完之后效果图如下:
还是此项目
添加一个消费者Consumer4 (监听testTopic)
@Component
@RabbitListener(queues = "testTopic")
public class Consumer4 {
@RabbitHandler
public void showMessage(String message){
System.out.println("testTopic接收到消息:"+message);
}
}
重启启动类
再添加一个测试方法
//topic主题模式 测试
//相比于路由模式只会改变了交换机的类型 topic 并且主题模式支持routingKey‘*’、‘#’占位符匹配
//‘error.*’匹配:error.log、error.sss.... 不匹配error.log.sss 而‘#’可以
/**
* 根据发送消息的routingKey来进行匹配
* 一个消息能被多个相匹配的消息对列获取
*/
@Test
public void testTopic() {
rabbitTemplate.convertAndSend("zhqTopic","error.log","RabbitMQ:使用主题模式发送了消息:error.log");
}
运行测试类控制台打印如下:
三个都配到了!