0.application.properties添加如下配置
# 消息发送至exchange callback
spring.rabbitmq.publisher-confirms=true
# 消息发送至queue 失败才callback
spring.rabbitmq.publisher-returns=true
# 消费消息手动删除
spring.rabbitmq.listener.simple.acknowledge-mode=manual
1.自定义RabbitmqConfig
@Configuration
public class RabbitmqConfig {
public static final String QUEUE = "queue";
public static final String DIRECT_EXCHANGE = "direct_exchange";
public static final String ROUTING_KEY = "routing";
@Bean
public Queue queue() {
return new Queue(QUEUE);
}
@Bean
public DirectExchange directExchange() {
return new DirectExchange(DIRECT_EXCHANGE);
}
@Bean
public Binding binding(Queue queue, DirectExchange directExchange) {
return BindingBuilder.bind(queue).to(directExchange).with(ROUTING_KEY);
}
}
2.自定义生产者
@Service
public class ProducerService implements ReturnCallback, ConfirmCallback {
private static final Logger logger = LoggerFactory.getLogger(ProducerService.class);
@Autowired
private RabbitTemplate rabbitTemplate;
@PostConstruct
private void init() {
rabbitTemplate.setConfirmCallback(this);
rabbitTemplate.setReturnCallback(this);
}
public void setRabbitTemplate(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
public void sendMessage(String routingKey, User user) {
logger.warn("[Send Message] ===============> " + user.toString());
rabbitTemplate.convertAndSend(RabbitmqConfig.DIRECT_EXCHANGE, routingKey, user);
}
/**
* 消息是否到交换机中都有callback
*/
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
logger.warn("[唯一标识] " + correlationData);
logger.warn("[结果] " + ack);
logger.warn("[失败原因] " + cause);
}
/**
* 消息没有到队列会调用该回调 (一般消息发送失败, 使用ReturnCallback就足够啦)
*/
@Override
public void returnedMessage(org.springframework.amqp.core.Message message, int replyCode, String replyText, String exchange, String routingKey) {
logger.warn("[主体] " + message);
logger.warn("[replyCode] " + replyCode);
logger.warn("[描述] " + replyText);
logger.warn("[exchange] " + exchange);
logger.warn("[routingKey] " + routingKey);
}
}
3.自定义消费者
@Component
public class ConsumerService {
private static final Logger logger = LoggerFactory.getLogger(ConsumerService.class);
@RabbitListener(queues = RabbitmqConfig.QUEUE)
public void message(User user, Message message, Channel channel) {
try {
// 消息删除
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
logger.warn("[Consumer Message 01] ===============> " + user.toString());
} catch (Exception e) {
throw new RuntimeException("处理消息失败");
}
}
}
4.测试
@Test
public void testToExchange() {
User user = new User();
user.setId(123L);
user.setUsername("tom");
producerService.sendMessage(RabbitmqConfig.ROUTING_KEY + "01", user);
}
@Test
public void testToQueue() {
User user = new User();
user.setId(456L);
user.setUsername("jack");
producerService.sendMessage(RabbitmqConfig.ROUTING_KEY, user);
}
源码 https://gitee.com/jsjack_wang/springboot-demo dev-rabbitmq002分支