spring:
rabbitmq:
host:
port:
username:
password:
virtual-host: /
listener:
simple:
acknowledge-mode: manual
retry:
enabled: true
max-attempts: 5
initial-interval: 2000
publisher-confirm-type: correlated
publisher-returns: true
自定义confirm和 returnedMessage
package com.test.mq;
import com.test.mq.production.TestProduction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
@Slf4j
public class CustomConfirmAndReturnCallback implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {
@Autowired
private RabbitTemplate rabbitTemplate;
@PostConstruct
public void init() {
rabbitTemplate.setMandatory(true);
rabbitTemplate.setConfirmCallback(this);
rabbitTemplate.setReturnsCallback(this);
}
@Override
public void confirm(CorrelationData correlationData, boolean isSendSuccess, String error) {
String id = correlationData != null ? correlationData.getId() : "";
if (isSendSuccess) {
log.info("发送消息到交换器成功, id:{}", id);
} else {
log.error("发送消息到交换器失败, id:{}, cause:{}", id, error);
}
}
@Override
public void returnedMessage(ReturnedMessage returnedMessage) {
String exchange = returnedMessage.getExchange();
if(exchange.equals(TestProduction.EXCHANGE_TEST)){
return;
}
log.info("消息被退回>>。msg:{}, replyCode:{}. replyText:{}, exchange:{}, routingKey :{}",
returnedMessage.getMessage(), returnedMessage.getReplyCode(), returnedMessage.getReplyText(),
exchange , returnedMessage.getRoutingKey());
}
}
生产者
package com.test.mq.production;
import com.jiuyi.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.UUID;
@Component
@Slf4j
public class TestProduction{
@Resource
private RabbitTemplate rabbitTemplate;
public static final String QUEUE_TEST = "queue_test";
public static final String EXCHANGE_TEST = "exchange_test";
@Bean(EXCHANGE_TEST)
public FanoutExchange EXCHANGE_TEST() {
return ExchangeBuilder.fanoutExchange(EXCHANGE_TEST).delayed().durable(true).build();
}
@Bean(QUEUE_TEST)
public Queue QUEUE_TEST() {
return new Queue(QUEUE_TEST, true);
}
@Bean
public Binding BINDING_QUEUE_TEST(@Qualifier(QUEUE_TEST) Queue queue,
@Qualifier(EXCHANGE_TEST) FanoutExchange exchange) {
return BindingBuilder.bind(queue).to(exchange);
}
public void send(String message, Integer delay) {
//msg id 唯一
CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
log.info("生产开始时间:" + DateUtils.getNowDate());
//发送消息时指定 header 延迟时间
rabbitTemplate.convertAndSend(EXCHANGE_TEST,
"", message,
message1 -> {
//设置消息持久化
message1.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
if (delay != null) {
message1.getMessageProperties().setDelay(delay*1000);
}
return message1;
}, correlationData);
log.info("生产结束时间:" + DateUtils.getNowDate());
}
}
消费者
package com.test.mq.listener;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Objects;
@Slf4j
@Component
public class TestListener {
@RabbitListener(
bindings = @QueueBinding(
value = @Queue(value = "queue_test", durable = "true", autoDelete = "false"),
exchange = @Exchange(value = "exchange_test",
type = ExchangeTypes.FANOUT, delayed = "true")
)
)
@RabbitHandler
public void process(Message msg, Channel channel) throws IOException {
String id = (String)msg.getMessageProperties().getHeader("spring_returned_message_correlation");
System.out.println("收到消息了,id:"+id);
long deliveryTag = msg.getMessageProperties().getDeliveryTag();
if (Objects.nonNull(msg.getBody())) {
System.out.println(new String(msg.getBody()));
System.out.println("收到消息了");
int i = 1 / 0;
}
channel.basicAck(deliveryTag, false);
}
}