以下内容基于上一篇springboot整合rabbitmq
1、重试
1.1 配置
消费者中添加如下配置
# 开启自动重试
spring.rabbitmq.listener.simple.retry.enabled=true
# 最大重试次数
spring.rabbitmq.listener.simple.retry.max-attempts=5
# 重试时间间隔
spring.rabbitmq.listener.simple.retry.initial-interval=3000
2、手动签收
2.1 配置
消费者中添加配置
# 消息确认:手动签收
spring.rabbitmq.listener.simple.acknowledge-mode=manual
2.1 消费者改造
EmailConsumer
package com.mine.consumer;
import java.io.IOException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
@Component
@RabbitListener(queues = "queue_email")
@Slf4j
public class EmailConsumer {
@RabbitHandler
public void process(String content, Message message, Channel channel) throws IOException {
log.info("接收到邮件队列消息:" + content);
// 手动签收
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}
}
3、幂等性问题
使用全局MessageId判断消息是否被消费过,解决幂等性问题。也可以用唯一的业务键代替。
3.1 生产者改造
MsgProducer
package com.mine.producer;
import java.util.UUID;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.mine.config.RabbitConfig;
import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
public class MsgProducer {
@Autowired
private AmqpTemplate amqpTemplate;
public void sendSms(String content) {
// 请求头设置消息id(messageId)
Message message = MessageBuilder.withBody(content.getBytes())
.setContentType(MessageProperties.CONTENT_TYPE_JSON).setContentEncoding("utf-8")
.setMessageId(UUID.randomUUID() + "").build();
amqpTemplate.convertAndSend(RabbitConfig.EXCHANGE_DIRECT, RabbitConfig.ROUTING_KEY_SMS, message);
log.info("sendSms success, message[" + message.getMessageProperties