springboot整合RabbitMQ生产者消息可靠投递
消息可靠投递confirm
这种方式可以确定交换机是否可以收到消息但是不能确认队列是否收到消息。如果队列找不到回调函数的参数仍旧是true
1.开启消息可靠投递confirm
老版本开启
spring.rabbitmq.publisher-confirms=true
新版本开启
spring.rabbitmq.publisher-confirm-type=correlated
publisher-confirm-type三种模式:
NONE值是禁用发布确认模式,是默认值
CORRELATED值是发布消息成功到交换器后会触发回调方法
SIMPLE值经测试有两种效果,其一效果和CORRELATED值一样会触发回调方法,其二在发布消息成功后使用rabbitTemplate调用waitForConfirms或waitForConfirmsOrDie方法等待broker节点返回发送结果,根据返回结果来判定下一步的逻辑,要注意的点是waitForConfirmsOrDie方法如果返回false则会关闭channel,则接下来无法发送消息到broker;
2.设置ConfirmCallback
@Controller
public class SendController {
@Autowired
RabbitTemplate rabbitTemplate;
@RequestMapping("sendMessage")
@ResponseBody
public String sendMessage(String message){
String messageId = String.valueOf(UUID.randomUUID());
String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Map<String,Object> map=new HashMap<>();
map.put("messageId",messageId);
map.put("messageData",message);
map.put("createTime",createTime);
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
/**
*
* @param correlationData 相关配置信息
* @param b 交换机是否成功收到消息
* @param s 失败原因
*/
@Override
public void confirm(CorrelationData correlationData, boolean b, String s) {
System.out.println("进入回调------------------------------------");
if(b){
System.out.println("消息接收成功");
}else{
System.out.println("消息接收失败"+s);
//消息接收失败处理代码
}
}
});
//将消息携带绑定键值:routingkey001发送到交换机directExchange
rabbitTemplate.convertAndSend("directExchange", "routingkey001", map);
return "ok";
}
消息可靠投递回退模式return
这种方式可以确认消息是否成功被队列接收
1.开启回退模式
spring.rabbitmq.publisher-returns=true
2.设置ReturnsCallback
旧版本默认消息失败会丢失不能返回给发送者,需要设置处理模式
rabbitTemplate.setMandatory(true);
我这使用的新版本默认是true
@Controller
public class SendController {
@Autowired
RabbitTemplate rabbitTemplate;
@RequestMapping("sendMessage")
@ResponseBody
public String sendMessage(String message){
String messageId = String.valueOf(UUID.randomUUID());
String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Map<String,Object> map=new HashMap<>();
map.put("messageId",messageId);
map.put("messageData",message);
map.put("createTime",createTime);
rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
@Override
public void returnedMessage(ReturnedMessage returnedMessage) {
System.out.println(returnedMessage.getReplyCode());//错误号
System.out.println(returnedMessage.getReplyText());//原因
System.out.println(returnedMessage.getRoutingKey());
System.out.println(returnedMessage.getExchange());
System.out.println(returnedMessage.getMessage());
System.out.println("进入回调------------------------------------"+returnedMessage.toString());
}
});
//将消息携带绑定键值:routingkey001发送到交换机directExchange
rabbitTemplate.convertAndSend("directExchange", "routingkey0011", map);
return "ok";
}