SpringBoot整合RabbitMQ

703 阅读2分钟

这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战

1.RabbitMQ依赖

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

2.配置RabbitMQ

2.1 配置RabbitMQ基本信息

spring:
  rabbitmq:
    host: 192.168.79.132
    username: admin
    password: admin
    port: 5672
    virtual-host: /
    connection-timeout: 15000
    # 发送确认
    publisherConfirmType: CORRELATED
    #开启路由失败回调
    publisher-returns: true
    template:
      # 必须设置成true 消息路由失败通知监听者,而不是将消息丢弃
      mandatory: true
      retry:
        #enabled:开启失败重试
        enabled: true
        #第一次重试的间隔时长
        initial-interval: 10000ms
        #最长重试间隔,超过这个间隔将不再重试
        max-interval: 30000ms
        #下次重试间隔的倍数,此处是2即下次重试间隔是上次的2倍
        multiplier: 2
    listener:
      simple:
        # 设置手动签收消息
        acknowledge-mode: manual

2.2 配置RabbitMQ消息转换器和回调监听器

import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * com.avatar.rabbit.config
 * Description:
 * RabbitMQ配置
 * 
 * @author jack
 * @date 2021/08/01 19:10
 */
@Configuration
public class RabbitConfig {

    @Bean
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(connectionFactory);
        /*
           Mandatory参数为true进行监听不可路由的消息,为false时,当消息不可路由时,直接删除掉。
         */
        rabbitTemplate.setMandatory(true);
        /*
         * ConfirmCallback()监听是否发送到broker
         * ReturnCallback()监听是否到队列:1. 当exchange不存在时,不会触发。2. 当exchange存在时,routingKey不匹配时,会触发。3. 当发送到队列时,不会触发
         * 1. exchange不存在时,触发ConfirmCallback()
         * 2. exchange存在时,routingKey不匹配时,先触发ReturnCallback(),再触发ConfirmCallback()
         * 3. 当exchange存在,routingKey也匹配时,只会触发ConfirmCallback()
         */
        rabbitTemplate.setConfirmCallback(new RabbitConfirmCallback());
        rabbitTemplate.setReturnCallback(new RabbitReturnCallback());
        return rabbitTemplate;
    }

}

2.3 监听消息是否发送到Broker

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

/**
 * com.avatar.rabbit.callback
 * Description:
 * 监听消息是否发送到broker
 *
 * @author jack
 * @date 2021/08/01 19:23
 */
@Slf4j
public class RabbitConfirmCallback implements RabbitTemplate.ConfirmCallback {

    /**
     * @param correlationData null
     * @param ack             是否发送到broker
     * @param cause           失败原因
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        log.info("***************confirmCallback begin***************");
        if (ack) {
            log.info("ConfirmCallback:     消息发送成功:ack:{}", ack);
        } else {
            log.error("ConfirmCallback:     消息发送失败:ack:{}", ack);
            log.error("ConfirmCallback:     失败原因:cause:{}", cause);
        }
        log.info("***************confirmCallback end***************");
    }
}

2.4 监听消息是否路由到队列

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

/**
 * com.avatar.rabbit.callback
 * Description:
 * 监听消息是否可路由
 *
 * @author jack
 * @date 2020/11/21 19:25
 */
@Slf4j
public class RabbitReturnCallback implements RabbitTemplate.ReturnCallback {
    /**
     * 查看说明: {@linkplain RabbitConfig#createRabbitTemplate(ConnectionFactory connectionFactory)}
     */
    @SuppressWarnings("NullableProblems")
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        log.error("***************returnCallback begin***************");
        log.error("ReturnCallback:     回应码:{}", replyCode);
        log.error("ReturnCallback:     回应信息:{}", replyText);
        log.error("ReturnCallback:     消息:{}", JSON.toJSONString(message));
        log.error("ReturnCallback:     交换机:{}", exchange);
        log.error("ReturnCallback:     路由键:{}", routingKey);
        log.error("***************returnCallback end***************");
    }
}

3.使用RabbitTemplate发送消息

@SpringBootTest
public class RabbitSendTest {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Test
    public void send() {
        rabbitTemplate.convertAndSend("test-directExchange", "test.send", "Hello");
    }

}