确认机制方案
代码架构图
配置文件
spring.rabbitmq.publisher-confirm-type=correlated
⚫ NONE
禁用发布确认模式,是默认值
⚫ CORRELATED
发布消息成功到交换器后会触发回调方法
⚫ SIMPLE
其一效果和CORRELATED值一样会触发回调方法, 其二在发布消息成功后使用rabbitTemplate调用waitForConfirms或waitForConfirmsOrDie方法 等待broker节点返回发送结果,根据返回结果来判定下一步的逻辑,要注意的点是 waitForConfirmsOrDie方法如果返回false则会关闭channel,则接下来无法发送消息到broker
spring.application.name=demo6
spring.rabbitmq.host=192.168.231.135
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=123
server.port=8989
spring.rabbitmq.publisher-confirm-type=CORRELATED
添加配置类
/**
* 发布确认的配置类
*/
@Configuration
@Slf4j
public class config {
public static final String CONFIRM_EXCHANGE_NAME="confirm.exchange";
public static final String CONFIRM_QUEUE_NAME="confirm.queue";
//声明业务交换机
@Bean("confirmExchange")
public DirectExchange confirmExchange()
{
return new DirectExchange(CONFIRM_EXCHANGE_NAME);
}
//声明确认队列
@Bean("confirmQueue")
public Queue confirmQueue()
{
return QueueBuilder.durable(CONFIRM_QUEUE_NAME).build();
}
//声明确认队列和绑定关系
@Bean
public Binding queueBinding(@Qualifier("confirmQueue") Queue queue,@Qualifier("confirmExchange") DirectExchange exchange)
{
return BindingBuilder.bind(queue).to(exchange).with("key1");
}
}
回调接口
@Component
@Slf4j
public class MyCallBack implements RabbitTemplate.ConfirmCallback {
@Override
public void confirm(CorrelationData correlationData, boolean ack ,String cause) {
String id=correlationData!=null?correlationData.getId():"";
if(ack)
{
log.info("交换机已经收到id为{}的消息",id);
}
else
{
log.info("交换机还未收到id未:{}的消息,原因是{}",cause);
}
}
}
消息生产者
@RestController
@RequestMapping("/confirm")
@Slf4j
public class produce {
public static final String confirm_exchange_name="confirm.exchange";
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private MyCallBack myCallBack;
@PostConstruct
public void init()
{
rabbitTemplate.setConfirmCallback(myCallBack);
}
@GetMapping("sendMessage1/{message}")
public void sendMessage1(@PathVariable String message)
{
//指定消息id为1
CorrelationData correlationData1=new CorrelationData("1");
String routingKey="key1";
rabbitTemplate.convertAndSend(confirm_exchange_name,routingKey,message+routingKey,correlationData1);
log.info("发送的消息的内容{}",message);
CorrelationData correlationData2=new CorrelationData("2");
routingKey="key2";
rabbitTemplate.convertAndSend(confirm_exchange_name,routingKey,message+routingKey,correlationData2);
log.info("发送的消息的内容{}",message);
}
}
消息消费者
@Component
@Slf4j
public class ConfirmConsumer {
public static final String CONFIRM_QUEUE_NAME="confirm.queue";
@RabbitListener(queues = CONFIRM_QUEUE_NAME)
public void receiveMsg(Message message)
{
String s = new String(message.getBody());
log.info("接收到队列confirm.queue消息:{}",s);
}
}
发送消息
http://localhost:8989/confirm/sendMessage1/3322