@Slf4j
@Configuration
@ConditionalOnProperty(prefix = MqProperties.PREFIX, name = "enabled", havingValue = "true")
public class RabbitMqConfig {
@Autowired
private CachingConnectionFactory connectionFactory;
// --------------------------------------------mq配置--------------------------------------------
/**
* 生产方的消息到达确认机制
* ConfirmCallback 不管消息有没有正确到达exchange,都会被触发
* --如果到达exchange,则confirm回调,ack=true
* --如果未道道exchange,则confirm回调,ack=false
* ReturnCallback 消息未正确到达队列时触发
* --如果到达queue,则不会触发回调
* --如果未到达queue,则触发回调
* @return
*/
@Bean
public RabbitTemplate rabbitTemplate() {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
rabbitTemplate.setMandatory(Boolean.TRUE);
// 不论消息是否正确到达交换机,都会触发回调
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
/**
* @param correlationData 消息
* @param ack 是否到达交换机的确认结果 true到达交换机 false未到达交换机
* @param cause 未到达交换机的原因
*/
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
if (!ack){
log.error("消息发送失败-未正确到达交换机\n消息:{}\n失败信息:{}", JSON.toJSONString(correlationData),cause);
// TODO 失败处理
}
}
});
// 只有消息未正确到达队列时,才会回调
rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
/**
* @param returnedMessage 消息
* @param replyCode 失败码
* @param replyText 失败原因
* @param exchange 使用的交换机
* @param routingKey 使用的路由键
*/
@Override
public void returnedMessage(Message returnedMessage, int replyCode, String replyText, String exchange, String routingKey) {
log.error("消息发送失败-未正确到达交换机\n消息:{}\失败码:{}\n失败原因:{}\n交换机:{}\n路由键:{}",
JSON.toJSONString(returnedMessage),
replyCode,
replyText,
exchange,
routingKey);
// TODO 重新发送
}
});
return rabbitTemplate;
}
// --------------------------------------------交换机声明--------------------------------------------
/**
* 声明直连交换机
* @return
*/
@Bean
public DirectExchange directExchange() {
return new DirectExchange(MQConstant.XXH_NOTICE_SERVICE);
}
/**
* 声明死信交换机
* @return
*/
@Bean
public DirectExchange dlxExchange() {
return new DirectExchange(MQConstant.XXH_NOTICE_SERVICE_DLX);
}
// --------------------------------------------队列声明--------------------------------------------
/**
* 声明邮件队列
* @return
*/
@Bean
public Queue emailQueue() {
Map<String, Object> params = new HashMap<>(2);
//声明当前队列绑定的死信交换机
params.put("x-dead-letter-exchange", MQConstant.XXH_NOTICE_SERVICE_DLX);
//声明当前队列的死信路由键
params.put("x-dead-letter-routing-key", MQConstant.XXH_NOTICE_DLX_KEY);
return QueueBuilder.durable(MQConstant.XXH_NOTICE_SERVICE_EMAIL_QUEUE).withArguments(params).build();
}
/**
* 声明企微消息队列-文本消息队列
* @return
*/
@Bean
public Queue wechatTextMsgQueue(){
return new Queue(MQConstant.XXH_NOTICE_SERVICE_ENTERPRISEWECHAT_TEXTMSG_QUEUE,true);
}
/**
* 声明短信队列
*
* @return
*/
@Bean
public Queue noteQueue() {
return new Queue(MQConstant.XXH_NOTICE_SERVICE_NOTE_QUEUE, true);
}
/**
* 声明死信队列
*
* @return
*/
@Bean
public Queue dlxQueue() {
return new Queue(MQConstant.XXH_NOTICE_DLX_QUEUE);
}
// --------------------------------------------交换机与队列绑定--------------------------------------------
/**
* 绑定直连交换机和邮件队列
* @return
*/
@Bean
public Binding bindingEmailQueue() {
return BindingBuilder.bind(emailQueue()).to(directExchange()).with(MQConstant.XXH_NOTICE_SERVICE_EMAIL_KEY);
}
/**
* 绑定直连交换机和企微文本消息队列
* @return
*/
@Bean
public Binding bindingWechatTextMsgQueue(){
return BindingBuilder.bind(wechatTextMsgQueue()).to(directExchange()).with(MQConstant.XXH_NOTICE_SERVICE_ENTERPRISEWECHAT_KEY_TEXT);
}
/**
* 绑定死信交换机和死信队列
* @return
*/
@Bean
public Binding dlcBinding() {
return BindingBuilder.bind(dlxQueue()).to(dlxExchange()).with(MQConstant.XXH_NOTICE_DLX_KEY);
}
/**
* 绑定交换机和短信队列
* @return
*/
@Bean
public Binding bindingNoteQueue(){
return BindingBuilder.bind(noteQueue()).to(directExchange()).with("xxh.notice.service.note_key");
}
}
RabbitMQ发送方消息确认机制
最新推荐文章于 2024-08-20 08:45:30 发布
该博客详细介绍了如何在Spring Boot中配置RabbitMQ,包括设置生产者消息到达确认机制、死信交换机和队列。通过 ConfirmCallback 和 ReturnCallback 处理消息发送的确认与错误回调,确保消息的可靠传递。同时,定义了多个队列并进行了交换机与队列的绑定。
摘要由CSDN通过智能技术生成