# 开启confirm确认机制
spring.rabbitmq.publisher-confirms=true
# 开启returnMessage
spring.rabbitmq.publisher-returns=true
spring.rabbitmq.template.mandatory=true
// 1. try住发送消息的代码,处理相应异常
try {
rabbitTemplate.convertAndSend("hello_fanout_exchange", "", context,correlationData);
} catch (AmqpConnectException e) {
log.info("发送失败");
//在这里做消息发送失败的处理
e.printStackTrace();
}
//2. 开启confirm机制,在confirm中处理返回结果
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
log.info("ack:{} cause:{} CorrelationData:{}", ack, cause, JSON.toJSONString(correlationData));
}
// 3. 开启returnMessage机制,在returnedMessage中处理相应结果
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
log.info("message:{}\n replyCode:{}\n replyCode:{}\n exchange:{}\n routingKey:{}",
JSON.toJSONString(message), replyCode, replyText, exchange, routingKey);
String content = new String(message.getBody());
log.info("content:{}",content);
}
# 开启手动ack
spring.rabbitmq.listener.direct.acknowledge-mode=manual
spring.rabbitmq.listener.simple.acknowledge-mode=manual
@RabbitHandler
public void process(Object o, Channel channel, Message message) {
String hello = new String(message.getBody());
log.info("Receiver:{}", hello);
try {
//处理业务逻辑(需要保证幂等性)
log.info("消息消费成功");
//消息确认
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (Exception e) {
log.info("消息消费失败");
}
}
生产者和消费者的消息类型问题,建议使用json数据格式,即String类型。在消费者的代码里可以使用Message.getBody()获取消息体,也可以直接响应类型的参数类型接受数据,建议使用Message.getBody()获取消息内容,这样在rabbitmq的管理后台就可以直接发送消息,而不用设置header。
消息重发机制
CREATE TABLE `rabbitmq_send_record` (
`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`content` varchar(500) DEFAULT NULL COMMENT '消息内容',
`exchange` varchar(30) DEFAULT NULL COMMENT '交换机名称',
`queue` varchar(30) DEFAULT NULL COMMENT '队列名称',
`routing_key` varchar(30) DEFAULT NULL COMMENT '路由key名称',
`ack` tinyint(1) unsigned DEFAULT '0' COMMENT '发送消息ack确认标识,默认为false,需要confirm回调确认消息送达exchange。0:未发送成功 1:发送成功',
`return_message` tinyint(1) unsigned DEFAULT '1' COMMENT 'exchange转发消息到队列,如果转发失败回调returnMessage方法,默认为true。0:转发失败 1:转发成功',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_ack` (`ack`) USING BTREE COMMENT '发送消息到exchange',
KEY `idx_return_message` (`return_message`) USING BTREE COMMENT 'exchange转发消息到队列'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;