RabbitMQ安装与使用
使用docker安装RabbitMQ
docker run -d --name rabbitmq -p 5671:5671 -p 5672:5672 -p 4369:4369 -p 25672:25672 -p 15671:15671 -p 15672:15672 rabbitmq:management
端口信息
5671、5672:AMQP端口
4369、25672:Erlang发现、集群端口
15672:web管理后台端口
61613、61614:STOMP协议端口
1883、8883:MQTT协议端口
文档:https://www.rabbitmq.com/networking.html
开启开机自启动
docker update rabbitmq --restart=always
web启动rabbitmq
https://主机地址:15672
登陆账号密码
账号:guest
密码:guest
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>2.4.6</version>
</dependency>
使用CTRL+N查自动配置类RabbitAutoConfiguration,如果存在说明生效
配置rabbitmq配置信息
spring.rabbitmq.host=****** rabbitmq主机地址
spring.rabbitmq.port=5672 端口号
spring.rabbitmq.virtual-host=/ 虚拟主机在网页rabbitmq中virtual-host中查看
启动类添加注解
@EnableRabbit
高级消息队列管理组件
AmqpAdmin amqpAdmin;
创建一个交换机
DirectExchange directExchange = new DirectExchange(名字,是否持久化,是否自动删除); 交换机
amqpAdmin.declareExchange(directExchange );
创建一个队列
Queue queue = new Queue(名字,持久化,是否排他,是否自动删除);
amqpAdmin.declareQueue(queue);
队列与交换机进行绑定
Binding binding = new Binding(
目的地(队列的名字),
目的地类型(Binding.DestinationType.QUEUE),
交换机名字,
路由键,
自定义参数
);
amqpAdmin.declareBinding(binding);
高级队列收发消息
RabbitTemplate rabbitTemplate; 收发消息
转换并发送
rabbitTemplate.convertAndSend(交换机,绑定的路由键,发送的消息);
如果发送的是一个对象,那么就会进行转换为相关的字节流数据进行发送
发送消息,如果发送的是一个对象,,我们会使用序列化机制将对象写出去,对象必须实现Serializable接口
如果我们这时需要将发送出去的对象信息进士可视化展示,我们这时就需自己写一个转换器。在RabbitAutoConfiguration->RabbitTemplate->MessageConverter,使用CTRL+H查看MessageConverter接口下的所有实现类,在AbstractMessageConverter->AbstractJackson2MessageConverter->Jackson2JsonMessageConverter用于json转换,所以在这里我们可以自己写一个类用于json转换
//此处MessageConverter应为amqp包下的MessageConverter
@Configuration
public class MyRabbitConfig{
@Bean
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
}
监听消息可以使用@EnableRabbitListener和@RabbitHandler,使用Rabbitmq相关功能可以不开启@EnableRabbit注解但是要监听Rabbitmq就必须要开启@EnableRabbit注解。方法中需要监听消息就需要在方法中开启@EnableRabbit注解,此注解必须在容器中
@EnableRabbitListener(quenes={"",""}) 可以监听多个队列,quenes声明需要监听的多个队列
必须有@EnableRabbit相关的功能才支持
可以添加在类+方法上
如何监听消息例如:
@EnableRabbitListener(quenes={"",""})
public void MyRabbitMq(Message message){
System.out.println(message);
}
参数类型
Message message原生消息类型 头+体
T<发送的消息类型> 对象 可以直接转化
Channel channel 当前传输类型的通道
服务可以启动多个,但是同一个消息,只会被一个客户端所收到。并且只有一个消息处理完,才会接收下一个消息。(消息一般不会丢失,如果此时是在单元测试的情况下,丢失的消息在控制台,并没有丢失消息)
@EnableRabbitListener与@RabbitHandler的区别
@EnableRabbitListener
可以添加在类+方法上
@RabbitHandler
只可以添加在方法上
类使用@EnableRabbitListener,方法上必须标注@RabbitHandler,类使用@EnableRabbitListener可以监听多个不同的消息
RabbitMq消息确认机制—可靠抵达
可靠抵达-ConfirmCallback(确认模式)
spring.rabbutmq.publsher-confirms=true(开启发送端确认)
- CorrelationData:用来表示当前消息的唯一性
- 消息只要被broker接收到就会执行ConfirmCallback,如果是在cluster模式,需要所有broker接收到才会调用ConfirmCallback。
- 被broker接收到只能表示message已经到达服务器,并不能保证消息一定会被投递到目标queue里,所以需要用到接下来的returnCallback。
配置文件开启发送端确认
spring.rabbutmq.publisher-confirms=true
定制RabbitTemplate
@Autowired
RabbitTemplate rabbitTemplate;
@PostConstruct //当前对象创建完成后,执行这个方法
public void ininRabbitTemplate(){
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback(){
/**
correlationData 当前消息的唯一关联数据(消息的唯一id)
ack 消息成功还是失败
cause 失败的原因
*/
@Override
public void confirm(CorrelationData correlationData,boolean ack,String cause){
}
});
}
只要消息能抵达服务器ack就是true,和是否被消费没有关系
可靠抵达-ReturnCallback
spring.rabbitmq.publisher-returns=true
spring.rabbitmq.template.mandatory=true
- confrim模式只能保证消息到达broker,不能保证消息准确投递到目标queue里,在有些业务场景下,我们需要保证消息一定要投递到目标queue里,此时就需要使用return回调模式。
- 这样如果未能投递到目标queue里,将调用returnCallback,可以记录下详细到投递数据,定期巡检或者自动纠错都需要这些数据。
开启配置
开启发送端消息抵达队列的确认
spring.rabbitmq.publisher-returns=true
只要抵达队列,以异步模式优先回调我们的这个returnconfirm
spring.rabbitmq.template.mandatory=true
消费者手动ack确认消息
spring.rabbitmq.listener.simple.acknowledge-mode=manual
手动确认
@RabbitHandler
public void recieveMessage(Message message,消息,Channel channel){
long deliveryTag = message.getMessageProperties().getDeliveryTag();
try{
//手动签收
channel.basicAck(deliveryTag,false(是否批量签收));
//手动拒收 消息,是否批量拒收,是否重新入队
channel.basicNack(deliveryTag,false,false);
//第二种拒收方案 消息,是否批量拒收
channel.basicReject();
}catch(Exception e){
}
}
确认模式
消费者手动ack确认消息
spring.rabbitmq.listener.simple.acknowledge-mode=manual
确认模式 confirm
spring.rabbitmq.publisher-confirm-type=correlated
是否支持重试
spring.rabbitmq.listener.simple.retry.enabled=true
Rabbitmq确认模式:https://zhuanlan.zhihu.com/p/152325703