文章目录
1 监听生产端消息回调方法的状态
关注点:发送方能不能放在队列去
1 能不能连上去
2 能不能发送到交换机里边
3 正确路由到queue
参考direct 的生产者和消费者而言,看下边的操作
https://blog.csdn.net/Insist___/article/details/105270456
1.1模拟监听不到的这三种情况
1.1.1 连不上去mq
修改了连接mq的访问端口
![](https://i-blog.csdnimg.cn/blog_migrate/5f2eae1741d7f40e9d148c245a2d75e4.png)
调用之前的direct方法
直接报错,代码就用try catch 。监控异常
1.1.2 exchange 不正常
1 调用方法时,调用了一个没有定义的交换机
调用访问地址,调用并不成功,但是却返回了一个ok .就具有了误导性。本质上消息并没有发送成功。
根据调用,并不知道是否发送成功。如果没有发送成功,在哪个环节出现问题?
1.1.3 路由不到队列
调用的时候,交换机正确,但是路由健不正确。
2 解决:
2.1 创建配置类
自己定义一个模版,用于回调的方法
注入bean,系统会用注入的bean,而不是默认的bean.
setConfirmCallback: 交换机不正确,会调用
setReturnCallback:没有正确的路由,会触发setReturnCallback
package fastwave.cloud.demo.fastwavebizpublisher.config;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.SerializerMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
@Configuration
public class TemplateConfig {
@Primary
@Bean
public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory){
RabbitTemplate rabbitTemplate = new RabbitTemplate();
rabbitTemplate.setConnectionFactory(connectionFactory);
//设置开启Mandatory,才能触发回调函数,无论消息推送结果怎么样都强制调用回调函数
rabbitTemplate.setMandatory(true);
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.out.println("ConfirmCallback: "+"相关数据:"+correlationData);
System.out.println("ConfirmCallback: "+"确认情况:"+ack);
System.out.println("ConfirmCallback: "+"原因:"+cause);
}
});
rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
System.out.println("ReturnCallback: "+"消息:"+message);
System.out.println("ReturnCallback: "+"回应码:"+replyCode);
System.out.println("ReturnCallback: "+"回应信息:"+replyText);
System.out.println("ReturnCallback: "+"交换机:"+exchange);
System.out.println("ReturnCallback: "+"路由键:"+routingKey);
}
});
return rabbitTemplate;
}
}
2.2 修改yml文件
spring:
application:
name: biz-publisher
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
# publisher-confirms: true
publisher-returns: true
publisher-confirm-type: correlated
server:
port: 8071
3 测试
3.1 交换机不正确时
3.2 路由key不正确时:
他会同时调用
setConfirmCallback : ack返回ture.证明交换机没有问题
setReturnCallback::没有路由 。
4 确认哪次业务操作发生了错误。(比如说订单ID为5678的订单的消息没有发送成功)
这条消息可能多次发送。但是并不知道具体是哪一次的业务关联的消息没有发送正确。
解决:
将相关业务数据保存进去:
比如说订单的订单ID。这样日后可以根据日志查找问题
@GetMapping("/noExchange")
public String noExchange(@RequestParam Map<String, Object> params)
{
try
{
String msg = params.get("msg").toString();
String uuid = UUID.randomUUID().toString();
template.convertAndSend("EmailExchange", "EmailRouting2", msg, new CorrelationData(uuid));
return "OK";
}
catch (Exception e)
{
return "网络中断,请稍后重试";
}
}