SpringBoot整合RabbitMQ——Topic 交换机


SpringBoot整合RabbitMQ——Topic 交换机

前言

使用SpringBoot对RabbitMQ进行整合,模拟生产者服务器(9002)向消费者服务器(8003)发送消息的过程,消息生产者通过接收 HTTP 请求向消息队列发送消息(Controller层、Service层),接收端则直接监听队列接收消息。这里的Demo分别设置有三个接口,每个接口向不同绑定路由规则的队列发送消息,观察消费者端接收情况。

关于RabbitMQ的搭建及搭建中常见的问题参考连接:RabbitMQ搭建及问题

简介

Topic交换机与Direct相似,通过与交换机绑定队列的路由键进行消息分发。不同的是Topic可以通过使用通配符( * 和 #)将消息分发到一个或者多个队列当中

通配符说明示例
*匹配一个或多个内容bigdata. * 可以匹配到 bigdata.spark 或者 bigdata.hadoop.hive 等
#匹配一个内容bigdata.# 只能匹配到 bigdata.spark 或者 bigdata.hadoop

img

依赖

在 pom.xml 文件中添加依赖,主要是 SpringBoot中 WEB 依赖 starter 和 amqp 的依赖 starter

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
    </parent>

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

application.yml 配置

消息生产者(发送端)配置,端口9002

server:
  port: 9002
spring:
  application:
    name: topic-sender
  rabbitmq:
    username: admin
    password: admin
    host: 192.168.108.128
    port: 5672

消费者(接收端)配置,端口8003

server:
  port: 8003
spring:
  application:
    name: topic-receiver
  rabbitmq:
    username: admin
    password: admin
    host: 192.168.108.128
    port: 5672

消息生产者(发送端)

SendConfig.java配置信息

在配置信息中创建三个队列分别为topic.queue.1、topic.queue.2、topic.queue.3,并且绑定到交换机上的路由键分别为topic.message.rabbit、topic.message.*、topic.#

@Component
public class SendConfig {
    public static final String TOPIC_QUEUE_1 = "topic.queue.1";
    public static final String TOPIC_QUEUE_2 = "topic.queue.2";
    public static final String TOPIC_QUEUE_3 = "topic.queue.3";
    public static final String TOPIC_EXCHANGE = "topic.exchange";
    public static final String TOPIC_ROUTING_KEY_1 = "topic.message.rabbit";
    public static final String TOPIC_ROUTING_KEY_2 = "topic.message.*";
    public static final String TOPIC_ROUTING_KEY_3 = "topic.#";

    @Bean
    public Queue queue1() {
        return new Queue(TOPIC_QUEUE_1);
    }

    @Bean
    public Queue queue2() {
        return new Queue(TOPIC_QUEUE_2);
    }

    @Bean
    public Queue queue3() {
        return new Queue(TOPIC_QUEUE_3);
    }

    @Bean
    public TopicExchange topicExchange() {
        return new TopicExchange(TOPIC_EXCHANGE);
    }

    @Bean
    public Binding binding1() {
        return BindingBuilder.bind(queue1()).to(topicExchange()).with(TOPIC_ROUTING_KEY_1);
    }

    @Bean
    public Binding binding2() {
        return BindingBuilder.bind(queue2()).to(topicExchange()).with(TOPIC_ROUTING_KEY_2);
    }

    @Bean
    public Binding binding3() {
        return BindingBuilder.bind(queue3()).to(topicExchange()).with(TOPIC_ROUTING_KEY_3);
    }

}

Controller层

demo中有三个接口发送消息,分别发送消息到三个不同的路由键上,用于观察哪些接收端接收到了对应消息

@RestController
@RequestMapping("/topic")
public class SendController {
    @Autowired
    private TopicService topicService;

    @GetMapping("/send1/{msg}")
    public void send1(@PathVariable String msg) {
        topicService.send1(msg);
    }

    @GetMapping("/send2/{msg}")
    public void send2(@PathVariable String msg) {
        topicService.send2(msg);
    }

    @GetMapping("/send3/{msg}")
    public void send3(@PathVariable String msg) {
        topicService.send3(msg);
    }
}

Service层

  • send1方法发送信息到路由键topic.message.rabbit
  • send2方法发送信息到路由键topic.message.kafka
  • send3方法发送信息到路由键topic
@Service
public class TopicServiceImpl implements TopicService {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public void send1(String msg) {
        System.out.println("路由键 topic.message.rabbit 发送消息:"+msg);
        rabbitTemplate.convertAndSend(SendConfig.TOPIC_EXCHANGE, "topic.message.rabbit", msg);
    }

    @Override
    public void send2(String msg) {
        System.out.println("路由键 topic.message.kafka 发送消息:"+msg);
        rabbitTemplate.convertAndSend(SendConfig.TOPIC_EXCHANGE, "topic.message.kafka", msg);
    }

    @Override
    public void send3(String msg) {
        System.out.println("路由键 topic 发送消息:"+msg);
        rabbitTemplate.convertAndSend(SendConfig.TOPIC_EXCHANGE, "topic", msg);
    }
}

消费者(接收端)

@Component
public class TopicReceive {

    @RabbitListener(queues = "topic.queue.1")
    public void receiveTopic1(String msg) {
        System.out.println("topic.queue.1 接收到数据:" + msg);
    }

    @RabbitListener(queues = "topic.queue.2")
    public void receiveTopic2(String msg) {
        System.out.println("topic.queue.2 接收到数据:" + msg);
    }

    @RabbitListener(queues = "topic.queue.3")
    public void receiveTopic3(String msg) {
        System.out.println("topic.queue.3 接收到数据:" + msg);
    }
}

测试

1.调用接口send1,发送到路由键topic.message.rabbit

http://127.0.0.1:9002/topic/send1/topic

控制台信息:
在这里插入图片描述
可以看到三个队列均接收到了信息
2.调用接口send2,发送到路由键topic.message.kafka

http://127.0.0.1:9002/topic/send2/topic

控制台信息:
在这里插入图片描述

只有队列2和队列3接收到数据
3.调用接口send3,发送到路由键topic

http://127.0.0.1:9002/topic/send3/topic

控制台信息:
在这里插入图片描述
只有队列1接收到信息

代码地址

RabbitDemo代码

参考

初识RabbitMQ——AMQP 0-9-1

RabbitMQ——RabbitMQ搭建及问题

SpringBoot整合RabbitMQ——Direct交换机

SpringBoot整合RabbitMQ——Fanout交换机

SpringBoot整合RabbitMQ——Headers交换机

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值