raabbitmq的消息可靠性
消息可靠性投递(针对生产者)
在使用 RabbitMQ的时候,作为消息发送方希望杜绝任何信息在任何地方丢失或者投递失败的情况。RabbitMQ为我们提供了两种方式用来控制消息的投递可靠性模式
消息投递步骤:生产者(channel)---->交换机------>队列中。
idea中的使用
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
(生产者)yml文件配置
在搭建好的springboot和rabbitMQ项目中的生产者子项目的配置文件application.yml文件中中开启rabbitMq的确认模式
spring:
rabbitmq:
host: 192.168.213.188
#开启rabbitMQ的生产方确认模式
publisher-confirm-type: correlated
# 开启发布者退回模式
publisher-returns: true
java代码编写
在service中编写
@Service
public class ProductServiceImpl implements ProductService {
//动态注入 RabbitTemolate类,用来操作rabbitMQ
@Autowired
RabbitTemplate rabbitTemplate;
//编写业务代码
@Override
public String product(int a ,int b) {
//往创建好的交换机中发送信息
rabbitTemplate.convertAndSend("ban129_exchange_direct","error", JSON.toJSON(a) );
//如果生产者往交换机发送信息后,会执行此方法 ,必须在配置文件中开启rabbitMQ的生产方确认模式
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean b, String s) {
//boolean b true为成功 ,false为失败
if(b==false){
//失败后可以执行自己想要的业务
System.out.println("失败");
}
}
});
//如果交换机往队列中插入信息失败后,会执行此方法,必须开启发布者退回模式
rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
@Override
public void returnedMessage(ReturnedMessage returnedMessage) {
System.out.println("失败");
}
});
return "下单成功";
}
}
消费队列信息时的安全性问题(针对消费者)
为何使用
消费端收到消息后的确认方式分为 ‘自动确认’、‘手动确认’。
其中自动确认是指,当消息一旦被Consumer接收到,则自动确认收到,并将相应 message 从 RabbitMQ 的消息队列中移除。但是在实际业务处理中,很可能消息接收到,业务处理出现异常,那么该消息就会丢失。 如果设置了手动确认方式,则需要在业务处理成功后,调用channel.basicAck(),手动签收,如果出现异常,则调用channel.basicNack()方法,让其自动重新发送消息。
idea使用
只要在父工程中引入 ‘amqp’依赖就不用再引依赖
(生产者)配置文件
spring:
rabbitmq:
host: 192.168.213.188
listener:
simple:
#表示手动确认
acknowledge-mode: manual
# 表示自动确认模式
# acknowledge-mode: none
监听类代码
@Component
public class Listener1 {
//监听的队列
@RabbitListener(queues = {"ban129_queue_direct01"})
//执行的方法
// Message参数是存放了队列的信息
//Channel参数是信道的信息
public void listener1(Message msg , Channel channel) throws Exception{
//获取唯一的标识 ID
long deliveryTag = msg.getMessageProperties().getDeliveryTag();
//获取正在消费的信息
byte[] body = msg.getBody();
String ms=new String(body);
try {
System.out.println("是西安");
//消费端手动确认消息
//long deliveryTag, 唯一标识 ID,当一个消费者向 RabbitMQ 注册后,会建立起一个 Channel ,RabbitMQ 会用 basic.deliver 方法向消费者推送消息,这个方法就携带了一个 delivery tag
// boolean multiple:是否允许多确认(true会消费掉其他堆积的信息,false不会)
//没有异常就消费并且把此信息从队列中移除
channel.basicAck(deliveryTag,true);
}catch (Exception e){
//有异常把此信息从队列中移除并且要求生产者重新发送此信息到队列中重新消费
channel.basicNack(deliveryTag,true,true);
}
}
}
消费端限流
只需要在消费者项目的配置文件中加入配置即可
1. 必须为手动确认模式。
2. 必须配置限流的个数。
spring:
rabbitmq:
host: 192.168.213.188
listener:
simple:
#表示手动确认
acknowledge-mode: manual
# 表示自动确认模式
# acknowledge-mode: none
# 设置每次消费的个数。
prefetch: 100
https://blog.youkuaiyun.com/pan_junbiao/article/details/112956537?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161900352116780255285202%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=161900352116780255285202&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-112956537.first_rank_v2_pc_rank_v29&utm_term=deliveryTag+