SpringBoot 整合 RabbitMQ


GitHub: link. 欢迎star

注意:本篇博客风格(不多比比就是撸代码!!!)

一、maven依赖

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-amqp -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
            <version>2.6.1</version>
        </dependency>

二、RabbitMQConfig.java

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;

/**
 * @author Andon
 * 2021/12/7
 */
@SpringBootConfiguration
public class RabbitMQConfig {

    // work模式
    @Value("${rabbitmq.work.queue-name}")
    private String queue_name_work;
    // 订阅模式
    @Value("${rabbitmq.fanout.queue-name-1}")
    private String queue_name_fanout_1;
    @Value("${rabbitmq.fanout.queue-name-2}")
    private String queue_name_fanout_2;
    @Value("${rabbitmq.fanout.exchange-name}")
    private String exchange_name_fanout;
    // topic模式
    @Value("${rabbitmq.topic.queue-name-1}")
    private String queue_name_topic_1;
    @Value("${rabbitmq.topic.routing-key-1}")
    private String routing_key_name_topic_1;
    @Value("${rabbitmq.topic.queue-name-2}")
    private String queue_name_topic_2;
    @Value("${rabbitmq.topic.routing-key-2}")
    private String routing_key_name_topic_2;
    @Value("${rabbitmq.topic.exchange-name}")
    private String exchange_name_topic;
    // 消息confirm机制
    @Value("${rabbitmq.confirm.queue-name}")
    private String queue_name_confirm;
    // 消息return机制
    @Value("${rabbitmq.return.queue-name}")
    private String queue_name_return;
    @Value("${rabbitmq.return.routing-key}")
    private String routing_key_name_return;
    @Value("${rabbitmq.return.exchange-name}")
    private String exchange_name_return;

    /**
     * work模式
     * <p>
     * 声明一个队列名称
     */
    @Bean
    public Queue queueWork() {
        return new Queue(queue_name_work);
    }

    /**
     * 订阅模式
     * <p>
     * 声明两个队列名称
     * 声明一个交换机
     * 交换机和队列进行绑定
     */
    @Bean
    public Queue queueFanout1() {
        return new Queue(queue_name_fanout_1);
    }

    @Bean
    public Queue queueFanout2() {
        return new Queue(queue_name_fanout_2);
    }

    @Bean
    public FanoutExchange exchangeFanout() {
        return new FanoutExchange(exchange_name_fanout);
    }

    @Bean
    public Binding bindingFanoutExchange1() {
        return BindingBuilder.bind(queueFanout1()).to(exchangeFanout());
    }

    @Bean
    public Binding bindingFanoutExchange2() {
        return BindingBuilder.bind(queueFanout2()).to(exchangeFanout());
    }

    /**
     * topic模式
     * <p>
     * 声明两个队列名称
     * 声明一个交换机
     * 交换机和队列进行绑定,队列和路由键进行绑定
     */
    @Bean
    public Queue queueTopic1() {
        return new Queue(queue_name_topic_1);
    }

    @Bean
    public Queue queueTopic2() {
        return new Queue(queue_name_topic_2);
    }

    @Bean
    public TopicExchange exchangeTopic() {
        return new TopicExchange(exchange_name_topic);
    }

    @Bean
    public Binding bindingTopicExchange1() {
        return BindingBuilder.bind(queueTopic1()).to(exchangeTopic()).with(routing_key_name_topic_1);
    }

    @Bean
    public Binding bindingTopicExchange2() {
        return BindingBuilder.bind(queueTopic2()).to(exchangeTopic()).with(routing_key_name_topic_2);
    }

    /**
     * 测试消息confirm机制
     * <p>
     * 声明一个队列
     */
    @Bean
    public Queue queueConfirm() {
        return new Queue(queue_name_confirm);
    }

    /**
     * 测试消息return机制
     * <p>
     * 声明一个队列
     * 声明一个交换机
     */
    @Bean
    public Queue queueReturn() {
        return new Queue(queue_name_return);
    }

    @Bean
    public TopicExchange exchangeReturn() {
        return new TopicExchange(exchange_name_return);
    }

    @Bean
    public Binding bindingReturnExchange() {
        return BindingBuilder.bind(queueReturn()).to(exchangeReturn()).with(routing_key_name_return);
    }
}

三、RabbitMQProducer.java

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author Andon
 * 2021/12/7
 * <p>
 * 生产者
 */
@Slf4j
@Component
public class RabbitMQProducer {

    @Resource
    private RabbitTemplate rabbitTemplate;
    // work模式
    @Value("${rabbitmq.work.queue-name}")
    private String queue_name_work;
    // 订阅模式
    @Value("${rabbitmq.fanout.exchange-name}")
    private String exchange_name_fanout;
    // topic模式
    @Value("${rabbitmq.topic.exchange-name}")
    private String exchange_name_topic;
    // 消息confirm机制
    @Value("${rabbitmq.confirm.queue-name}")
    private String queue_name_confirm;
    // 消息return机制
    @Value("${rabbitmq.return.exchange-name}")
    private String exchange_name_return;

    /**
     * work模式
     * <p>
     * 消息直接发送到消息队列
     * 一个生产者,多个消费者,每个消息只能被一个消费者消费
     */
    public void sendWork(String message) {
        rabbitTemplate.convertAndSend(queue_name_work, message);
    }

    /**
     * 订阅模式
     * <p>
     * 消息发送到交换机
     * 一个生产者,多个消费者,每个消息被每个消费者消费
     */
    public void sendFanout(String message) {
        rabbitTemplate.convertAndSend(exchange_name_fanout, "", message);
    }

    /**
     * topic模式
     * <p>
     * 消息发送到交换机
     * 一个生产者,多个消费者,每个消息被每个对应路由键的消费者消费
     */
    public void sendTopic(String routingKey, String message) {
        rabbitTemplate.convertAndSend(exchange_name_topic, routingKey, message);
    }

    /**
     * 消息confirm机制
     */
    public void sendConfirm(Object message) {
        CorrelationData correlationData = new CorrelationData(Thread.currentThread().getId() + "_" + System.currentTimeMillis());
        rabbitTemplate.convertAndSend(queue_name_confirm, message, correlationData);
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                if (ack) {
                    log.info("消息confirm成功!! id:{}", correlationData.getId());
                } else {
                    log.info("消息confirm失败!! id:{} cause:{}", correlationData.getId(), cause);
                }
            }
        });
    }

    /**
     * 消息return机制
     * <p>
     * return 的回调方法(找不到路由才会触发)
     */
    public void sendReturn(String routingKey, String message) {
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            @Override
            public void returnedMessage(ReturnedMessage returned) {
                log.info("returnedMessage >> exchange:{} routingKey:{} getMessage:{} replyCode:{} replyText:{}", returned.getExchange(), returned.getRoutingKey(), returned.getMessage(), returned.getReplyCode(), returned.getReplyText());
            }
        });
        rabbitTemplate.convertAndSend(exchange_name_return, routingKey, message);
    }
}

四、RabbitMQConsumer.java

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @author Andon
 * 2021/12/7
 * <p>
 * 消费者
 */
@Slf4j
@Component
public class RabbitMQConsumer {

    // work1
    @RabbitListener(queues = "${rabbitmq.work.queue-name}")
    public void consumeWork1(String message) {
        log.info("consumeWork1 message:{}", message);
    }

    // work2
    @RabbitListener(queues = "${rabbitmq.work.queue-name}")
    public void consumeWork2(String message) {
        log.info("consumeWork2 message:{}", message);
    }

    // 订阅1
    @RabbitListener(queues = "${rabbitmq.fanout.queue-name-1}")
    public void consumeFanout1(String message) {
        log.info("consumeFanout1 message:{}", message);
    }

    // 订阅2
    @RabbitListener(queues = "${rabbitmq.fanout.queue-name-2}")
    public void consumeFanout2(String message) {
        log.info("consumeFanout2 message:{}", message);
    }

    // topic1
    @RabbitListener(queues = "${rabbitmq.topic.queue-name-1}")
    public void consumeTopic1(String message) {
        log.info("consumeTopic1 message:{}", message);
    }

    // topic2
    @RabbitListener(queues = "${rabbitmq.topic.queue-name-2}")
    public void consumeTopic2(String message) {
        log.info("consumeTopic2 message:{}", message);
    }

    // 消息confirm机制
    @RabbitListener(queues = "${rabbitmq.confirm.queue-name}")
    public void consumeConfirm(String message) {
        log.info("consumeConfirm message:{}", message);
    }

    // 消息return机制
    @RabbitListener(queues = "${rabbitmq.return.queue-name}")
    public void consumeReturn(String message) {
        log.info("consumeReturn message:{}", message);
    }
}

五、application.yml

spring:
  # RabbitMQ
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: admin
    password: admin
    # 配置虚拟机
    virtual-host: /
    # 开启消息确认机制 confirm 异步
    publisher-confirm-type: correlated
    # 开启return机制
    publisher-returns: true
    # 消息开启手动确认
    listener:
      direct:
        acknowledge-mode: manual

rabbitmq:
  work:
    queue-name: queue_work
  fanout:
    queue-name-1: queue_fanout_1
    queue-name-2: queue_fanout_2
    exchange-name: exchange_fanout
  topic:
    queue-name-1: queue_topic_1
    routing-key-1: topic.#
    queue-name-2: queue_topic_2
    routing-key-2: topic.*
    exchange-name: exchange_topic
  confirm:
    queue-name: queue_confirm
  return:
    queue-name: queue_return
    exchange-name: exchange_return
    routing-key: return.*

六、DatabaseTest.java

import com.andon.springbootrabbitmq.rabbitmq.RabbitMQProducer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

/**
 * @author Andon
 * 2021/12/7
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class DatabaseTest {

    @Resource
    private RabbitMQProducer rabbitMQProducer;

    @Test
    public void test05() {
        rabbitMQProducer.sendReturn("return.an.return", "return!!");
    }

    @Test
    public void test04() {
        rabbitMQProducer.sendConfirm("confirm!!");
    }

    @Test
    public void test03() {
        for (int i = 0; i < 10; i++) {
            if (i % 2 == 0) {
                rabbitMQProducer.sendTopic("topic.an.topic", "topic" + i);
            } else {
                rabbitMQProducer.sendTopic("topic.an", "topic" + i);
            }
        }
    }

    @Test
    public void test02() {
        for (int i = 0; i < 10; i++) {
            rabbitMQProducer.sendFanout("fanout" + i);
        }
    }

    @Test
    public void test01() {
        for (int i = 0; i < 10; i++) {
            rabbitMQProducer.sendWork("work" + i);
        }
    }
}

七、测试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

GitHub: link. 欢迎star

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值