前言
本节主要涉及到Rabbitmq在SpringBoot的API使用,基本是上一节的一个扩展,也会简单的介绍一下七种模型和Header Exchange的使用,不过使用场景从原生变成了SpringBoot封装。
对于七种模型和Header Exchange的介绍会很简单提及,如果想详细了解,可以看一下上一节内容。
一 Hello Word
Hello Word 模型采用默认Exchange,以Queue Name作为RoutingKey的方式进行消息发布。
具体实现如下
1.1 配置文件
spring:
application:
name: Rabbitmq-AMQP
rabbitmq:
host: ****** # 这里填写ip
port: 5672
virtual-host: /test # 虚拟主机
username: admin
password: admin
1.2 Consumer
/**
* @author heshuai
* @title: HelloWordConsumer
* @description: HelloWord模型 消息消费者
* 这里需要介绍几个注解
* @Component: Spring IOC注解,注入当前对象实例到ICO容器
* @RabbitListener: Rabbitmq监听器,监听Queue来接受消息,这个注解中包含了常用的接受消息时所涉及到的方法
* id:唯一标识该监听器,可以自动生成,无需特殊设置
* containerFactory:容器工厂,生成RabbitListener容器所用,一般使用默认工厂即可
* queues:所监听Queue的名称,可以为数组,即监听多个Queue;注:所指定Queue必须存在,或者在其它位置开始声明对应的bean
* queuesToDeclare:声明并监听该Queue,可以使用@Queue()去描述Queue
* exclusive:true,单一消息中独占Queue,并且要求并发量为1;false:默认
* bindings: 绑定Exchange和Queue,@QueueBinding可以使用这个注解去定义QueueBinding对象
* @Queue: 定义一个Queue对象,这个注解在queuesToDeclare属性中可以使用
* 在这个对象中,可以定义一个常规的Queue的所有配置,这个和之前Simple-module中的内容基本一致
* @date 2021年01月29日 11:17
*/
@Component
@RabbitListener(queuesToDeclare = @Queue("helloWord"))
public class HelloWordConsumer {
/**
* @RabbitListener 可以使用在类上或者是方法上,如果使用在类上,需要指定类中的一个方法作为接受消息的方法,
* 所以这里使用了@RabbitHandler
* 可以使用Object去接收消息,也可以使用String去接收:如果使用Object,那么接受的是Message对象,里面包含消息体、消息头等参数信息(不可以使用Message对象去直接接受)
* 如果使用String去接收,则只是接收到消息体
* @param message
*/
/*
@RabbitHandler
public void receive(Object message){
System.out.println("收到消息如下:");
System.out.println(new String(((Message)message).getBody()));
}*/
@RabbitHandler
public void receive(String message){
System.out.println("收到消息如下:");
System.out.println(message);
}
}
1.3 Producer
@SpringBootTest(classes = SpringbootModuleApplication.class)
class SpringbootModuleApplicationTests {
/**
* RabbitTemplate
* SpringFramework 提供一个类似于RedisTemplate、RestTemplate这些的一个高度封装的模板,
* 就是对于amqp-client的封装(没看过底层、猜测)
* 简单介绍一下功能
* 除了可以send、receive,还对这两个重载了很多方法,而且提供了更多如:convertAndSend、convertSendAndReceive这些更加深入的封装方法,
* 基本上也就是对于发送消息和接受消息的各种角度的封装了;
* 这个类中还包含一些特殊的默认值设置,比如:encoding、exchange、routingKey、defaultReceiveQueue,可以更加浓缩代码;
* 这里有个必须设置的配置项就是connectionFactory,不过这个也是可以通过application.yml直接配置的,没什么区别
* 除了这些以外还有一个事务的设置(setChannelTransacted()),这个就不深入了
*/
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* HelloWord 模型 消息发布
*/
@Test
void helloWord() {
/**
* 为了介绍这个方法,使用这个方法重载最多参数的方法
* exchange:交换机名字,“”就是默认交换机
* routingKey:路由Key, 使用AMQP中的默认交换机,默认与所有的queue相绑定,queue名就是他们的绑定key
* object:发送的消息内容,因为convertAndSend方法对这个进行了封装,所以可以直接发送对象,不局限byte数组了
* CorrelationData:这个应该是用于发布者确认模型中所需要用到的参数
*/
rabbitTemplate.convertAndSend("","helloWord",String.format("我是一个简简单单的HelloWord\n你好!这个世界!\n愿世间没有病痛\n"), (CorrelationData)null);
}
}
二、WorkQueue
当多个Consumer监听同一个Queue时,即是所谓的WorkQueue,Rabbitmq会采用轮询的方式将Queue的消息发送给C1、C2,不会造成同一条消息的重复消费!
具体实现如下
1. Consumer
/**
* @author heshuai
* @title: WorkQueueConsumer
* @description: 工作模型——WorkQueue
* 因为需要在一个类中写多个监听处理,所以将@RaabitListener直接写到方法上机课
* @date 2021年02月02日 11:05
*/
@Component
public class WorkQueueConsumer {
/**
* @RabbitListener: 可以直接添加到方法上,表示该方法就是Rabbitmq监听器处理函数
*/
@RabbitListener(queuesToDeclare = @Queue(name = "workQueue"))
public void workQueue1(String message){
System.out.println("workQueue1收到消息如下:");
System.out.println(message);
}
@RabbitListener(queuesToDeclare = @Queue(name = "workQueue"))
public void workQueue2(String message){
System.out.println("workQueue2收到消息如下:");
System.out.println(message);
}
}
2. Provider
/**
* WorkQueue 模型 消息发布
*/
@Test
void workQueue(){
for (int i=0; i<10; i++){
rabbitTemplate.convertAndSend("workQueue",String.format("这是第"+i+"条祝福\n"));
}
}
三 Publish/Subscribe
订阅发布模式:官方的解释是一次性发布消息给多个Consumer,这里的Consumer可以理解成Queue,因为Consumer都是监听相应的Queue的!
如果需要实现一次性这个关键的话,那么必须使用AMQP协议中的Exchange概念,前两个模式使用的都是默认的Exchange,在下面这些模式中将去主动声明使用Exchange来进行转发Message。
具体实现如下
1. Consumer
/**
* @author heshuai
* @title: SubscribeConsumer
* @description: 发布订阅模式: 这个模式是基于AMQP协议中Exchange概念,所以等下主要是看Exchange
* @Component: 交给Spring管理
* @date 2021年02月08日 16:45
*/
@Component
public class SubscribeConsumer {
/**
* 接受消息方法:
* @RabbitListener: bindings属性代表绑定Exchange和Queue,并且定义他们的RoutingKey
* @Exchange: 定义一个Exchange,根据它的模式定义,如果这个Exchange不存在则主动创建一个Exchange,type类型默认Direct。
* 并且在这个注解中支持x-delayed-message类型,默认 false
* @param message
*/
@RabbitListener(bindings = @QueueBinding(