简单工作模型
接下来我们使用该SpringBoot的注解进行操作MQ,简单模型对应着上面的基础使用,创建参数也有介绍,如有需要使用工厂模式进行操作可以根据这两个的参数对比进行转换。
yml配置
server:
port: 9999
spring:
application:
name: rabbit-mq-learn
swagger2:
enabled: true
rabbitmq:
port: 5672
host: 43.138.25.182
username: admin
password: 123456
virtual-host: rabbitmq
常量
public class RabbitMqConstant {
/**
* 直练队列名称
*/
public final static String QUEUE_SIMPLE_QUEUE = "simple_queue";
/**
* 交换机名称
*/
public final static String EXCHANGE_SIMPLE_CHANGE = "simple_change";
/**
* routing key名称
*/
public final static String ROUTING_SIMPLE_ROUTING = "simple_routing";
}
监听器
@Component
public class RabbitMQListener {
@RabbitListener(queues = RabbitMqConstant.QUEUE_SIMPLE_QUEUE)
public void messageReceive(String message){
System.out.println("直连消息接收:"+message);
}
}
消息发送
@ApiModel(value = "AmqpSendController",description = "整合amqp进行消息推送")
@RestController
@RequestMapping("/amqpSend")
public class AmqpSendController {
@Autowired
private AmqpTemplate amqpTemplate;
@Autowired
private RabbitTemplate rabbitTemplate;
@PostMapping("/simple/{message}")
public void send(@PathVariable(value = "message") String message){
System.out.println("发送消息:"+message);
//rabbitTemplate.convertAndSend(RabbitMqConstant.QUEUE_SIMPLE_QUEUE,message);
amqpTemplate.convertAndSend(RabbitMqConstant.QUEUE_SIMPLE_QUEUE,message);
}
}
上述案例的发送方式有两种,都可使用
channel.basicPublish()
方式(基础使用的教程中)rabbitTemplate.send()
方式amqpTemplate.send()
方式2 和 3 都是对 1 的进一步封装
消息确认
在上面的那种接收中还会遇到点问题。
- 在消息接收处理时,如何保证消息是被处理的,没有因为设备原因导致没有处理完成?
- 消息发送时,如何确保消息被MQ接收到了?
解决处理:
- 在消息消费时针对重要的信息进行手动确认处理
- 重新配置实现
RabbitTemplate.ConfirmCallback
和RabbitTemplate.ReturnCallback
- ConfirmCallback是一个回调接口,消息发送到 Broker 后触发回调,确认消息是否到达 Broker 服务器,也就是只确认是否正确到达 Exchange 中。
- ReturnCallback 接口,启动消息失败返回,此接口是在交换器路由不到队列时触发回调,该方法可以不使用,因为交换器和队列是在代码里绑定的,如果消息成功投递到Broker后几乎不存在绑定队列失败,除非你代码写错了。
@Configuration
@Log4j2
public class RabbitMqConfirm implements RabbitTemplate.ReturnsCallback,RabbitTemplate.ConfirmCallback{
@Autowired
private RabbitTemplate rabbitTemplate;
@PostConstruct
public void initRabbitTemplate() {
// 设置生产者消息确认
rabbitTemplate.setConfirmCallback(this);
rabbitTemplate.setReturnsCallback(this);
}
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.out.println("ack:[{}]" + ack);
if (ack) {
log.info("消息发送成功{}",correlationData);
System.out.println("消息到达rabbitmq服务器");
} else {
// 通知处理或是放入死信队列重发
log.warn(cause);
System.out.println("消息可能未到达rabbitmq服务器");
}
}
@Override
public void returnedMessage(ReturnedMessage returned) {
log.info("消息主体 message : " + returned.getMessage());
log.info("消息主体 replyCode : " + returned.getReplyCode());
log.info("描述 replyText:" + returned.getReplyText());
log.info("消息使用的交换器 exchange : " + returned.getExchange());
log.info("消息使用的路由键 routing : " + returned.getRoutingKey());
}
}
server:
port: 9999
spring:
application:
name: rabbit-mq-learn
swagger2:
enabled: true
rabbitmq:
port: 5672
host: 43.138.25.182
username: admin
password: 123456
virtual-host: rabbitmq
publisher-returns: true #启用
publisher-confirm-type: simple #确认方式 SIMPLE CORRELATED NONE
- SIMPLE: 这种确认类型使用
RabbitTemplate#waitForConfirms()
或者在受限范围内使用waitForConfirmsOrDie()
来等待确认。简单来说,它等待直到消息已经被确认或者确认失败。 - CORRELATED: 这种确认类型需要与
CorrelationData
一起使用,以便将确认与发送的消息相关联。通常在需要跟踪每条消息的状态时使用,通过为每条消息指定唯一的CorrelationData
来关联确认信息。 - NONE: 这是默认的确认类型,表示发布者确认被禁用。在这种情况下,
去除用户对应的Virtual Hosts
权限测试发布消息