RabbitMQ 之 Exchange 交换机的讲解与基本使用(直连交换机&&主题交换机&&扇形交换机)

"本文详细介绍了RabbitMQ中的三种交换机类型:直连交换机、主题交换机和扇形交换机。通过配置示例展示了如何创建队列、交换机以及绑定,并提供了生产者发送信息和消费者接收信息的代码。直连交换机基于完全匹配的路由键将消息发送到队列;主题交换机允许使用通配符进行路由,如 "*.orange.*";扇形交换机则会将消息广播到所有绑定的队列。"

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,什么是交换机

交换机类型:

实战

1,pom 依赖在上一篇博客中

RabbitMQ 的基本使用

2,生产者和消费者的yml文件

server:
  port: 8081
spring:
  application:
    name: scz
  rabbitmq:
    host: 47.98.177.61
    password: 123456
    port: 5672
    username: springboot
    virtual-host: my_vhost
server:
  port: 8082
spring:
  application:
    name: scz
  rabbitmq:
    host: 47.98.177.61
    password: 123456
    port: 5672
    username: springboot
    virtual-host: my_vhost

二,直连交换机

1,DirectConfig  生产者创建队列和交换机

package com.lgs.scz.mq;

import com.rabbitmq.client.AMQP;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
@SuppressWarnings("all")
public class DirectConfig {

    /**
     * 创建队列
     */
    @Bean
    public Queue DirectQueueA(){
        return new Queue("DirectQueueA",true);
    }

    @Bean
    public Queue DirectQueueB(){
        return new Queue("DirectQueueB",true);
    }

    @Bean
    public Queue DirectQueueC(){
        return new Queue("DirectQueueC",true);
    }

    /**
     * 创建交换机
     */
    @Bean
    public DirectExchange directExchange(){
        return new DirectExchange("directExchange");
    }


    /**
     *进行交换机和队列的绑定  设置bindingkey
     */
    @Bean
    public Binding bindingA(){
        return BindingBuilder.bind(DirectQueueA()).to(directExchange()).with("AA");
    }

    @Bean
    public Binding bindingB(){
        return BindingBuilder.bind(DirectQueueB()).to(directExchange()).with("BB");
    }

    @Bean
    public Binding bindingC(){
        return BindingBuilder.bind(DirectQueueC()).to(directExchange()).with("CC");
    }

}

2,ProviderController  生产者发送信息

package com.lgs.scz.controller;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SuppressWarnings("all")
public class ProviderController {

    @Autowired
    private RabbitTemplate template;

    @RequestMapping("/DirectSend")
    public String DirectSend(String routingKey){
        template.convertAndSend("directExchange",routingKey,"你好你好!来俄罗斯打仗吗!!!");
        return "yes";
    }


}

3,  DirectReceiverA   消费者接收信息  

package com.lgs.xfz.mq;

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

@Component
@SuppressWarnings("all")
@RabbitListener(queues = "DirectQueueA")
@Slf4j
public class DirectReceiverA {

    @RabbitHandler
    public void process(String message){
        log.info("A接到"+message);
    }

}

三,主题交换机

1,TopicConfig  生产者创建队列和交换机和定义路由键

package com.lgs.scz.mq;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//主题交换机

@Configuration
@SuppressWarnings("all")
public class TopicConfig {

    /**
     * 定义路由键
     */
    public final static String KEY_A="*.orange.*";
    public final static String KEY_B="*.*.rabbit";
    public final static String KEY_C="lazy.#";

    /**
     * 创建队列
     */
    @Bean
    public Queue TopicQueueA(){
        return new Queue("TopicQueueA",true);
    }

    @Bean
    public Queue TopicQueueB(){
        return new Queue("TopicQueueB",true);
    }

    @Bean
    public Queue TopicQueueC(){
        return new Queue("TopicQueueC",true);
    }

    /**
     * 创建交换机
     */
    @Bean
    public TopicExchange topicExchange(){
        return new TopicExchange("topicExchange");
    }


    /**
     *进行交换机和队列的绑定  设置bindingkey
     */
    @Bean
    public Binding TopicbindingA(){
        return BindingBuilder.bind(TopicQueueA()).to(topicExchange()).with(KEY_A);
    }

    @Bean
    public Binding TopicbindingB(){
        return BindingBuilder.bind(TopicQueueB()).to(topicExchange()).with(KEY_B);
    }

    @Bean
    public Binding TopicbindingC(){
        return BindingBuilder.bind(TopicQueueC()).to(topicExchange()).with(KEY_C);
    }

}

2,ProviderController  生产者发送信息

package com.lgs.scz.controller;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SuppressWarnings("all")
public class ProviderController {

    @Autowired
    private RabbitTemplate template;


    @RequestMapping("/TopicSend")
    public String TopicSend(String routingKey){
        template.convertAndSend("topicExchange",routingKey,"你好你好!来俄罗斯打仗吗!!!");
        return "yes";
    }


}

3,  TopicReceiverA  消费者接收信息  

package com.lgs.xfz.mq;

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

@Component
@SuppressWarnings("all")
@RabbitListener(queues = "FanoutQueueA")
@Slf4j
public class TopicReceiverA {

    @RabbitHandler
    public void process(String message){
        log.warn("A接到"+message);
    }

}

四,扇形交换机

1,FanoutConfig  生产者创建队列和交换机

package com.lgs.scz.mq;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//扇形交换机

@Configuration
@SuppressWarnings("all")
public class FanoutConfig {

    /**
     * 创建队列
     */
    @Bean
    public Queue FanoutQueueA(){
        return new Queue("FanoutQueueA",true);
    }

    @Bean
    public Queue FanoutQueueB(){
        return new Queue("FanoutQueueB",true);
    }

    @Bean
    public Queue FanoutQueueC(){
        return new Queue("FanoutQueueC",true);
    }

    /**
     * 创建交换机
     */
    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange("fanoutExchange");
    }


    /**
     *进行交换机和队列的绑定
     */
    @Bean
    public Binding FanoutbindingA(){
        return BindingBuilder.bind(FanoutQueueA()).to(fanoutExchange());
    }

    @Bean
    public Binding FanoutbindingB(){
        return BindingBuilder.bind(FanoutQueueB()).to(fanoutExchange());
    }

    @Bean
    public Binding FanoutbindingC(){
        return BindingBuilder.bind(FanoutQueueC()).to(fanoutExchange());
    }

}

2,ProviderController  生产者发送信息

package com.lgs.scz.controller;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SuppressWarnings("all")
public class ProviderController {

    @Autowired
    private RabbitTemplate template;

    @RequestMapping("/FanoutSend")
    public String FanoutSend(){
        template.convertAndSend("fanoutExchange",null,"你好你好!来俄罗斯打仗吗!!!");
        return "yes";
    }

}

3,FanoutReceiverA  消费者接收信息  

package com.lgs.xfz.mq;

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

@Component
@SuppressWarnings("all")
@RabbitListener(queues = "TopicQueueA")
@Slf4j
public class FanoutReceiverA {

    @RabbitHandler
    public void process(String message){
        log.warn("A接到"+message);
    }

}

OK!到这就结束了,希望能帮到你!!!

### RabbitMQ 扇形交换机 (Fanout Exchange)使用配置 #### 定义特性 扇形交换机是一种特殊的交换机类型,其工作原理非常简单:它接收消息并将这些消息广播到所有绑定的队列中。这意味着发送给该类型的交换机的消息会被复制并分发至每一个其关联的队列里。 #### 配置方法 为了创建一个fanout类型的exchange,在声明时指定`'fanout'`作为type参数即可: ```java // Java示例代码 AMQP.Exchange.DeclareOk declareExchange = channel.exchangeDeclare("logs", "fanout"); ``` 对于Python客户端而言,则可以这样定义: ```python # Python示例代码 channel.exchange_declare(exchange='logs', exchange_type='fanout') ``` 一旦建立了这样的交换机之后,任何连接到此交换机上的消费者都将接收到相同的数据流副本[^1]。 #### 发布消息 向这个特定名称的交换机发布一条新消息只需要指明目标exchange的名字以及不需要设置routing key因为在这个模式下路由键被忽略掉了: ```java // Java示例代码 String message = "Hello World!"; channel.basicPublish("logs", "", null, message.getBytes()); System.out.println(" [x] Sent '" + message + "'"); ``` 对应的Python版本如下所示: ```python # Python示例代码 message = 'hello world' channel.basic_publish( exchange='logs', routing_key='', body=message, ) print(f" [x] Sent {message}") ``` #### 接收端处理逻辑 在消费侧,每个监听者都需要独立地建立自己的临时匿名queue并上述提到过的exchange进行绑定操作以便于能够捕获到来自生产者的每条记录: ```java // Java示例代码 QueueingConsumer consumer = new QueueingConsumer(channel); channel.basicConsume(queueName, true, consumer); while (true) { QueueingConsumer.Delivery delivery = consumer.nextDelivery(); String msg = new String(delivery.getBody()); System.out.println("Received Message: " + msg); } ``` 而用Python实现同样的功能则更为简洁直观一些: ```python # Python示例代码 def callback(ch, method, properties, body): print(f" Received {body}") channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True) print(' [*] Waiting for messages.') channel.start_consuming() ``` 以上就是关于如何利用RabbitMQ中的fanout exchange来构建简单的日志收集系统的介绍[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亣柒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值