SpringCloud系列教程:微服务的未来(二十四)Direct交换机、Topic交换机、声明队列交换机

前言

在现代消息队列系统中,交换机是实现消息传递和路由的核心组件。本文将重点探讨三种常见的交换机类型:Direct交换机、Topic交换机和声明队列交换机。通过对这三种交换机的详细分析,我们将学习它们的工作原理、应用场景以及如何在实际项目中选择合适的交换机类型。无论你是刚接触消息队列的初学者,还是有一定经验的开发者,相信本篇博客能帮助你更深入地理解交换机的基本概念,并帮助你在使用消息中间件时做出更好的设计决策。


Direct交换机

Direct Exchange 会将接收到的消息根据规则路由到指定的Queue,因此称为定向路由。

  • 每一个Queue都与Exchange设置一个BindingKey
  • 发布者发送消息时,指定消息的RoutingKey
  • Exchange将消息路由到BindingKey与消息RoutingKey一致的队列

利用SpringAMQP演示DirectExchange的使用

需求如下:

  1. 在RabbitMQ控制台中,声明队列direct.queue1和direct.queue2
  2. 在RabbitMO控制台中,声明交换机hmall.direct,将两个队列与其绑定
  3. 在consumer服务中,编写两个消费者方法,分别监听direct.queue1和direct.queue2
  4. 在publisher中编写测试方法,利用不同的RoutingKey向hmall.direct发送消息

创建队列direct.queue1和direct.queue2

创建交换机hmall.direct

声明 routing key并绑定队列


消费者代码如下:

java 复制代码
	@RabbitListener(queues = "direct.queue1")
    public void listenDirectQueue1(String message)throws Exception {
        log.info("消费者1监听到direct.queue2的消息,["+message+"]");
    }
    @RabbitListener(queues = "direct.queue2")
    public void listenDirectQueue2(String message)throws Exception {
        log.info("消费者2监听到direct.queue2的消息,["+message+"]");
    }

测试代码如下:

java 复制代码
	@Test
    public void TestDirectQueue(){
        //1.交换机名
        String exchangeName = "hmall.direct";
        //2.消息
        String message = "Hello 红色!";
        //3.发送消息 
        rabbitTemplate.convertAndSend(exchangeName,"red", message);
    }

运行结果如下:

测试代码如下:

java 复制代码
	@Test
    public void TestDirectQueue(){
        //1.交换机名
        String exchangeName = "hmall.direct";
        //2.消息
        String message = "Hello 蓝色!";
        //3.发送消息 
        rabbitTemplate.convertAndSend(exchangeName,"blue", message);
    }

运行结果如下:
Direct交换机与Fanout交换机的差异:

  • Fanout交换机将消息路由给每一个与之绑定的队列
  • Direct交换机根据RoutingKey判断路由给哪个队列
  • 如果多个队列具有相同RoutingKey,则与Fanout功能类似

Topic交换机

TopicExchange也是基于RoutingKey做消息路由,但是routingKey通常是多个单词的组合,并且以,分割。

Queue与Exchange指定BindingKey时可以使用通配符:

  • #:代表0个或多个单词
  • *:代表一个单词

利用SpringAMQP演示DirectExchange的使用

需求如下:

  1. 在RabbitMQ控制台中,声明队列topic.queue1和topic.queue2
  2. 在RabbitMQ控制台中,声明交换机hmall.topic,将两个队列与其绑定
  3. 在consumer服务中,编写两个消费者方法,分别监听topic.queue1和topic.queue2
  4. 在publisher中编写测试方法,利用不同的RoutingKey向hmall.topic发送消息

创建队列topic.queue1和topic.queue2

创建交换机hmall.topic

绑定队列关系


消费者代码如下:

java 复制代码
	@RabbitListener(queues = "topic.queue1")
    public void listenTopicQueue1(String message)throws Exception {
        log.info("消费者1监听到topic.queue1的消息,["+message+"]");
    }
    @RabbitListener(queues = "topic.queue2")
    public void listenTopicQueue2(String message)throws Exception {
        log.info("消费者2监听到topic.queue2的消息,["+message+"]");
    }

测试代码如下:

java 复制代码
	@Test
    public void TestTopicQueue(){
        //1.交换机名
        String exchangeName = "hmall.topic";
        //2.消息
        String message = "Hello 今日新闻!";
        //3.发送消息 参数分别是:交换机名称、RoutingKey(暂时为空)、消息
        rabbitTemplate.convertAndSend(exchangeName,"china.news", message);
    }

运行结果如下:

当routing key为china.weather,运行结果如下:

Topic交换机相比Direct交换机的差异:

  • Topic的RoutingKey和bindingKey可以是多个单词,以.分割
  • Topic交换机与队列绑定时的bindingKey可以指定通配符
  • #:代表0个或多个词
  • *:代表1个词

声明队列交换机

SpringAMQP提供了几个类,用来声明队列、交换机及其绑定关系:

  • Queue:用于声明队列,可以用工厂类QueueBuilder构建
  • Exchange:用于声明交换机,可以用工厂类ExchangeBuilder构建
  • Binding:用于声明队列和交换机的绑定关系,可以用工厂类BindingBuilder构建

例如,声明一个Fanout类型的交换机,并且创建队列与其绑定:

java 复制代码
@Configuration
public class FanoutConfig{
	//声明FanoutExchange交换机
	@Bean
	public FanoutExchange fanoutExchange(){
		return new FanoutExchange("hmall.fanout");
	}
	//声明第1个队列
	@Bean
	public Queue fanoutQueuel(){
		return new Queue(fanout.queue1);
	}
	//绑 定队列1和交换机
	@Bean
	public Binding bindingQueuel(Queue fanoutQueuel, FanoutExchange fanoutExchange){
		return BindingBuilder.bind(fanoutQueuel).to(fanoutExchange);
	}
	//...略,以相同方式声明第2个队列,并完成绑定中 
}
java 复制代码
@Configuration
public class FanoutConfig{
	//声明FanoutExchange交换机
	@Bean
	public FanoutExchange fanoutExchange(){
		return ExchangeBuilder.fanoutExchange("hmall.fanout").build();
	}
	//声明第1个队列
	@Bean
	public Queue fanoutQueuel(){
		return QueueBuilder.durable("fanout.queue1").build();
	}

通常在消费者这一端声明队列和交换机

java 复制代码
package com.itheima.consumer.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;



@Configuration
public class FanoutConfiguration {
    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange("hmall.fanout");
    }
    @Bean
    public Queue fanoutQueue1(){
        return new Queue("fanout.queuue1");
    }
    @Bean
    public Binding fanoutQueue1binding( Queue fanoutQueue1, FanoutExchange fanoutExchange){
        return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);

    }
    @Bean
    public Queue fanoutQueue2(){
        return new Queue("fanout.queuue2");
    }
    @Bean
    public Binding fanoutQueue2binding( Queue fanoutQueue2, FanoutExchange fanoutExchange){
        return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange);

    }
}

总结

通过本文的学习,我们深入了解了Direct交换机、Topic交换机和声明队列交换机的特点和使用场景。Direct交换机适用于点对点的消息传递,Topic交换机适合广播和发布/订阅模式,而声明队列交换机则在确保消息可靠性和一致性方面发挥重要作用。每种交换机都有其独特的优势和适用场景,掌握它们的应用将有助于我们在设计消息系统时做出更明智的选择。在实际项目中,了解这些基础概念将提升我们架构设计的能力,确保系统的高效性和稳定性。

相关推荐
lisw051 小时前
连接蓝牙时“无媒体信号”怎么办?
人工智能·机器学习·微服务
可我不想做饼干1 小时前
微服务注册中心 Spring Cloud Eureka是什么?
微服务
北风朝向2 小时前
Spring Boot参数校验8大坑与生产级避坑指南
java·spring boot·后端·spring
龙茶清欢4 小时前
Spring Boot 应用启动组件加载顺序与优先级详解
java·spring boot·后端·微服务
RainbowSea4 小时前
4. ChatClient 的初始,快速使用上手
java·spring·ai编程
RainbowSea4 小时前
3. Ollama 安装,流式输出,多模态,思考模型
java·spring·ai编程
即兴随缘6 小时前
【RabbitMQ】主题(Topics)与主题交换机(Topic Exchange)
rabbitmq·.net
蜚鸣7 小时前
Spring依赖注入方式
spring
麦兜*8 小时前
Redis数据迁移实战:从自建到云托管(阿里云/腾讯云)的平滑过渡
java·spring boot·redis·spring·spring cloud·阿里云·腾讯云
echoyu.8 小时前
微服务-分布式追踪 / 监控工具大全
分布式·微服务·架构