一.简介
- 1.Acknowledge,消费端收到消息后的确认方式
- 2.自动确认方式:acknowledge=“none”
- 3.手动确认方式:acknowledge=“manual”
- 4.根据异常确认方式:acknowledge=“auto”
- 5.自动确认方式,当消息被消费者接收到,自动确认收到,然后将message从rabbitmq的消息队列中移除。
- 6.手动确认方式,在业务处理成功后,调用channel.basicAck()手动签收,如果出现异常,则调用channel.basicNack()并让该消息重新放回队列。
二.消费端代码示例
1.pom.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot-learning</artifactId>
<groupId>com.learning</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springboot-rabbitmq-consumer</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- rabbitmq依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.application.yml配置
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
virtual-host: /
# 消费端手动消息确认
listener:
direct:
acknowledge-mode: manual
3.消息监听
package com.learning;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.io.IOException;
/**
* @Author wangyouhui
* @Description
* Consumer ACK机制
* 1.设置手动签收。 acknowledge="manual"
* 2.让监听器类实现ChannelAwareMessageListener接口
* 3.如果消息处理成功,则调用channel的basicAck()签收
* 4.如果消息处理失败,则调用channel的basicNack()拒绝签收,broker重新发送给consumer
**/
@Component
public class AckListener {
@RabbitListener(queues = "boot_queue")
public void onMessage(Message message, Channel channel) throws Exception {
// 演示效果,睡眠1s
Thread.sleep(1000);
long deliveryTag = message.getMessageProperties().getDeliveryTag();
try {
// 1. 接收转换消息
System.out.println(message.getBody());
// 2. 处理业务逻辑
System.out.println("处理业务逻辑...");
int a = 3/0;
// 3. 手动签收
channel.basicAck(deliveryTag, true);
} catch (IOException e) {
e.printStackTrace();
// 4.拒绝签收
/**
* requeue: 重回队列。如果设置为true,则消息重新回到queue,broker会重新发送该消息给消费端
*/
channel.basicNack(deliveryTag, true, true);
}
}
}
4.测试截图