springboot 整合最新rabbitMQ
pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--非必须-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
发送端yml
spring:
rabbitmq:
# 其它一些没有配置的必要属性springboot提供了默认值
# 发送端
#publisher-confirms: true # 在2.3版中已经弃用由 publisher-confirm-type 由 ConfirmType 代替
publisher-confirm-type: correlated # 消息发送成功确认
publisher-returns: true # 是否返回消息
template:
mandatory: true # 配合消息返回一起使用,没有对应的队列接受该消息就返回,而不是丢弃
关于publisher-confirm-type 的simple 和 correlated,笔者并未测试出有哪里不同,官方文档的说明比较模糊:
Publisher Confirms and Returns:
Confirmed (with correlation) and returned messages are supported by setting the CachingConnectionFactory property publisherConfirmType to ConfirmType.CORRELATED and the publisherReturns property to ‘true’.
就是说要想消息确认(publisher-confirm)和消息返回(publisher-returns)被支持,请将publisherConfirmType设置为CORRELATED 类型并且设置 publisherReturns 为true。而事实上,测试发现simple同样能达到消息确认(publisher-confirm)和消息返回(publisher-returns)。
关于simple,他的代码注释是这样的:Use {@code RabbitTemplate#waitForConfirms()} (or {@code waitForConfirmsOrDie()} within scoped operations. 官方的示例中说明批量确认的时候建议使用simple类型。
When using confirms in this way, much of the infrastructure set up for correlating confirms to requests is not really needed (unless returns are also enabled). Starting with version 2.2, the connection factory supports a new property called publisherConfirmType. When this is set to ConfirmType.SIMPLE, the infrastructure is avoided and the confirm processing can be more efficient.
发送端代码
/**
* @Author lucky
* @Description
* @Date 16:51 2021/3/26
* @Param massage 发送的消息 properties 消息的属性
* @return
**/
public void sendMessage(String massage, MessageProperties messageProperties) throws InterruptedException {
/**
* @Author lucky
* @Description 后置处理器
* @Date 17:07 2021/3/26
**/
MessagePostProcessor messagePostProcessor = (message) -> {
// 此处可以对消息进行后续处理
log.info("###########后置处理器{}############",new String(message.getBody()));
return message;
};
/**
* @Author lucky
* @Description
* @Date 16:46 2021/3/26
* @Param
* correlationData 可以作为消息唯一标识
* ack broker是否确认成功
* cause broker确认不成功的原因
**/
// 设置消息发送成功确认回调 publisher-confirm
rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
log.info("######confirmCallback------correlationData:{},ack:{},cause:{}",correlationData, ack, cause);
});
// 返回消息回调
rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
log.info("######returnCallback-----message:{},replyCode:{},replyText:{},exchange:{},routingKey:{},#######");
});
// 唯一标识
CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
rabbitTemplate.convertSendAndReceive("ex.rabbit", "key.rabbit", massage,
messagePostProcessor,correlationData);
}
消费者yml
spring:
rabbitmq:
# 其它一些没有配置的必要属性springboot提供了默认值
# 消费端
listener:
simple:
acknowledge-mode: manual # 手动签收
concurrency: 5 # listener调用程序线程的最小数量
max-concurrency: 10 # listener调用程序线程的最大数量。
direct:
acknowledge-mode: manual
消费者代码
/**
* @Author lucky
* @Description 监听者 可以省略 @RabbitHandler
* @Date 17:25 2021/3/26
* @Param
* @return
**/
@RabbitListener(
bindings = {
@QueueBinding(
value = @Queue(value = "queue.rabbit",durable = "true"),
// exchange 其他都有默认值 type默认为direct
exchange = @Exchange(name = "ex.rabbit",type = "topic"),
key = "key.#"
)
}
)
public void handleMessage(Message message, Channel channel) throws IOException {
// 收到消息之后进行业务处理
log.info("############消费消息--{}#############",new String(message.getBody()));
/**
* @Author lucky
* @Description 然后进行手动ack 让消息从unacked 中消失
* @Date 17:29 2021/3/26
* @Param DeliveryTag false 是否批量ack
* @return
**/
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
}
至此,简单地springboot整合就完成了。