SprintBoot使用RabbitMQ

1、配置RabbitMQ

1.1、创建交换机

创建交换机的时候需要指定虚拟主机以及交换机的类型(direct(路由模式)、fanout(广播)、headers、topic)

  • direct:Exchange通过消息携带的路由键来将消息分发到对应的队列中
  • fanout:Exchange将消息分发到所有绑定到交换机的队列中
  • headers:Exchange通过判断消息头的值是否与绑定的值相匹配来分发消息

x-match为any时,消息头的任意一个值匹配就可以满足条件
x-match为all时,消息头的所有值匹配才能满足条件

  • topic:Exchange将满足路由规则的消息分发到对应的队列

1.2、创建队列

创建队列时需要绑定到交换机上

 

2、SpringBoot使用RabbitMQ

2.1、导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

2.2、生产者发送消息

修改配置文件

spring.rabbitmq.host=192.168.1.100
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=123456

#虚拟主机
spring.rabbitmq.virtual-host=host3

#可以确保消息成功发送到交换器
spring.rabbitmq.publisher-confirm-type=correlated
#可以确保消息在未被队列接收时返回,通常会和mandatory属性配合一起使用
spring.rabbitmq.publisher-returns=true
#指定消息在没有被队列接收时是否强行退回还是直接丢弃
spring.rabbitmq.template.mandatory=true

spring.rabbitmq.publisher-confirm-type 属性用来配置消息发送到交换机之后是否触发回调方法。

有三种确认类型:

  • NONE:禁用发布确认模式,是默认值
  • CORRELATED:发布消息成功到交换器后会触发回调方法
  • SIMPLE:有两种效果,其一效果和CORRELATED值一样会触发回调方法,其二在发布消息成功后使用rabbitTemplate调用waitForConfirms或waitForConfirmsOrDie方法等待broker节点返回发送结果,根据返回结果来判定下一步的逻辑,要注意的点是waitForConfirmsOrDie方法如果返回false则会关闭channel,则接下来无法发送消息到broker;

生产者发布消息

//注入AmqpTemplate
private RabbitTemplate amqpTemplate;
public void sendMessage() {
    //通过convertAndSend方法发送消息
    String msg = "hello world";
    amqpTemplate.convertAndSend("Exchange1", "message", msg);
}

定义回调

@Slf4j
@Component
public class ReturnCallbackService implements RabbitTemplate.ReturnsCallback {
    @Override
    public void returnedMessage(ReturnedMessage returnedMessage) {
        log.info("returnedMessage ===> {}", returnedMessage.getMessage());
    }
}
@Slf4j
@Component
public class ConfirmCallbackService implements RabbitTemplate.ConfirmCallback {
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (!ack) {
            log.error("消息发送异常! cause={}", cause);
        } else {
            log.info("发送者已经收到确认");
        }
    }
}

 消息确认回调方法:

/**
* 设置生产者消息publish-confirm回调函数
*/
amqpTemplate.setConfirmCallback(confirmCallbackService);

//或者
amqpTemplate.setConfirmCallback((correlationData, ack, cause) -> {
    if (!ack) {
        log.error("消息发送异常! Id={}, ack={}, cause={}", correlationData.getId(), ack, cause);
    } else {
        log.info("发送者已经收到确认,Id={}", correlationData.getId());
    }
});

 消息退回回调方法:

/**
* 确保消息发送失败后可以重新返回到队列中
* 注意:yml需要配置 publisher-returns: true
*/
amqpTemplate.setMandatory(true);

/**
* 消息投递到队列失败回调处理
*/
amqpTemplate.setReturnsCallback(returnCallbackService);

2.3、消费者接收消息

修改配置文件

spring.rabbitmq.host=192.168.1.100
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=123456

#虚拟主机
spring.rabbitmq.virtual-host=host3

#监听异常重试次数
spring.rabbitmq.listener.simple.retry.max-attempts=3
#是否开启重试
spring.rabbitmq.listener.simple.retry.enabled=true
#重试间隔
spring.rabbitmq.listener.simple.retry.initial-interval=3000ms

#是否开启拒绝
spring.rabbitmq.listener.simple.default-requeue-rejected=false
#确认机制 自动 手动
spring.rabbitmq.listener.simple.acknowledge-mode=manual

SpringBoot中提供监听器来监听队列
@RabbitListener注解监听队列
@RabbitHandle注解作用于方法,用来处理消息

@RabbitListener(queues = "queue1")
@RabbitHandler
public void getMsg(String msg, Channel channel, Message message) throws IOException {
    try {
        log.info("message队列收到消息:{}", msg);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }  catch (Exception e) {
        if (message.getMessageProperties().getRedelivered()) {
            log.error("消息已重复处理失败,拒绝再次接收...");
            channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
        } else {
            log.error("消息即将再次返回队列处理...");
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/watson2017/article/details/124716716