rabbitmq 交换机相关实例代码

文章介绍了如何在Spring框架中使用RabbitMQ实现扇形交换机(fanoutexchange)和主题交换机(topicexchange),包括队列定义、绑定以及发送和接收端的示例。

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

1.扇形交换机

    定义扇形交换机和队列

package com.macro.mall.portal.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 RabbitMqFanoutQueueConfig {
 
    //=================== fanout 模式下,所发的消息属于广播模式  ====================
 
    /**
     *  定义队列 fanout.a  fanout.b fanout.c
     */
    @Bean
    public Queue fanoutA() {
        return new Queue("fanout.a");
    }
 
    @Bean
    public Queue fanoutB() {
        return new Queue("fanout.b");
    }
 
    @Bean
    public Queue fanoutC() {
        return new Queue("fanout.c");
    }
 
 
    /**
     * 定义个fanout交换器
     */
    @Bean
    FanoutExchange fanoutExchange() {
        // 定义一个名为fanoutExchange的fanout交换器
        return new FanoutExchange("fanoutExchange");
    }
 
    /**
     * 将队列fanout.a  fanout.b fanout.c  分别 与fanout交换器绑定
     */
    @Bean
    public Binding bindingExchangeWithA() {
        return BindingBuilder.bind(fanoutA()).to(fanoutExchange());
    }
 
    @Bean
    public Binding bindingExchangeWithB() {
        return BindingBuilder.bind(fanoutB()).to(fanoutExchange());
    }
 
    @Bean
    public Binding bindingExchangeWithC() {
        return BindingBuilder.bind(fanoutC()).to(fanoutExchange());
    }

}

 定义扇形交换机发送端,发送时,第二个参数是路由,不需要设置

 @Autowired
    private AmqpTemplate amqpTemplate;

    @PostMapping("/fanoutMsg")
    @Operation(summary = "发送扇形消息", description = "发送扇形消息")
    public String sendMsg() {
        amqpTemplate.convertAndSend("fanoutExchange","","扇形交换机消息");
        return "ok";
    }

定义扇形交换机接收端

package com.macro.mall.portal.component;

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

/**
 * @Description  扇形消息接收
 * @Author clj
 * @Date 2023/11/3 16:57
 */
@Component
@Slf4j
public class FanoutReceive {

    @RabbitListener(queues = "fanout.a")
    public void consumers(String msg) {
        log.info("[faount.a] recvice,{}",msg);
    }

    @RabbitListener(queues = "fanout.b")
    public void consumers2(String msg) {
        log.info("[faount.b] recvice,{}",msg);
    }

    @RabbitListener(queues = "fanout.c")
    public void consumers3(String msg) {
        log.info("[faount.c] recvice,{}",msg);
    }
}

当点击发送后,以上三个方法都会接受到消息,不需要路由。

2主题交换机

   定义交换机和队列,其中路由可以根据规则匹配,*表示匹配一个任意字符,#表示一个或多个

package com.macro.mall.portal.config;

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

/**
 * topic消息测试
 * @Author clj
 * @Date 2023/11/6 16:52
 */
@Configuration
public class RabbitmqTopicQueueConfig {

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


    @Bean
    public Queue topicA() {
        return new Queue("topic.a");
    }

    @Bean Queue topicB() {
        return new Queue("topic.b");
    }

    @Bean Queue topicC() {
        return new Queue("topic.c");
    }

    @Bean
    public Binding bindingTopicA() {
        return BindingBuilder.bind(topicA()).to(topicExchange()).with("topic.a");
    }

    @Bean
    public Binding bindingTopicB() {
        return  BindingBuilder.bind(topicB()).to(topicExchange()).with("topic.*.msg");
    }


    @Bean
    public Binding bindingTopicC() {
        return BindingBuilder.bind(topicC()).to(topicExchange()).with("topic.msg.#");
    }

}

 定义主题交换机发送端

 @PostMapping("/topicMsg")
    @Operation(summary = "发送主题交换机精确匹配a", description = "发送主题交换机精确匹配a")
    public String sendTopicMsg() {
        amqpTemplate.convertAndSend("topicExchange","topic.a","发送主题交换机a");
        return "ok";
    }

    @PostMapping("/topicMsg1")
    @Operation(summary = "发送主题交换机精确匹配b。匹配*号", description = "发送主题交换机精确匹配cb")
    public String sendTopicMsg1() {
        amqpTemplate.convertAndSend("topicExchange","topic.1.msg","发送主题交换机b");
        return "ok";
    }

    @PostMapping("/topicMsg9")
    @Operation(summary = "发送主题交换机精确匹配b。匹配*号", description = "发送主题交换机精确匹配cb")
    public String sendTopicMsg9() {
        amqpTemplate.convertAndSend("topicExchange","topic.2.msg","发送主题交换机b");
        return "ok";
    }

    @PostMapping("/topicMsg2")
    @Operation(summary = "发送主题交换机路由匹配c,匹配#号1", description = "发送主题交换机路由匹配")
    public String sendTopicMs2g() {
        amqpTemplate.convertAndSend("topicExchange","topic.msg.1","发送主题交换机c");
        return "ok";
    }
    @PostMapping("/topicMsg3")
    @Operation(summary = "发送主题交换机路由匹配c,匹配#号2", description = "发送主题交换机路由匹配")
    public String sendTopicMs3g() {
        amqpTemplate.convertAndSend("topicExchange","topic.msg.2","发送主题交换机c");
        return "ok";
    }

    @PostMapping("/topicMsg4")
    @Operation(summary = "发送主题交换机路由匹配c,匹配#号4", description = "发送主题交换机路由匹配")
    public String sendTopicMs4g() {
        amqpTemplate.convertAndSend("topicExchange","topic.msg.abcdefg","发送主题交换机c");
        return "ok";
    }

定义主题交换机接收端

package com.macro.mall.portal.component;

import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.annotation.Header;

import java.io.IOException;

/**
 * @Description
 * @Author clj
 * @Date 2023/11/6 17:01
 */
@Configuration
@Slf4j
public class topicReceive {

    @RabbitListener(queues = "topic.a")
    public void execute(String msg, Channel channel,@Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
        log.info("topicA接收精确匹配消息,{}",msg);
        channel.basicAck(tag,false);
    }

    @RabbitListener(queues = "topic.b")
    public void execute1(String msg) {
        log.info("topicB接收*号匹配消息,{}",msg);
    }


    @RabbitListener(queues = "topic.c")
    public void execute3(String msg) {
        log.info("topicC接收#匹配消息,{}",msg);
    }
}

### 配置RabbitMQ交换机 #### Header类型交换机简介 Header类型的交换机不依赖于消息中的路由键,而是通过匹配消息头(headers)属性来进行消息分发。这种机制允许更灵活的消息过滤方式[^1]。 #### 创建Header类型交换机实例 为了创建一个header类型的交换机,在管理插件的Web界面中可以完成此操作;也可以利用AMQP客户端库编程接口实现自动化部署。下面给出Python语言下的Pika库示例代码: ```python import pika connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() # 声明exchange, exchange_type='headers' channel.exchange_declare(exchange='test_headers_exchange', exchange_type='headers') # 关闭连接 connection.close() ``` 上述脚本定义了一个名为`test_headers_exchange`的header型交换器。 #### 绑定队列至Header交换机并设置匹配条件 当绑定队列到header交换机上时,需指定一组key-value形式的头部参数作为匹配规则。只有满足这些约束的消息才会被转发给对应的队列。继续上面的例子,增加一条带有特定头部信息的队列绑定语句如下所示: ```python result = channel.queue_declare(queue='', exclusive=True) queue_name = result.method.queue binding_keys = {'x-match': 'all', 'header_key':'value'} for key in binding_keys: channel.queue_bind( exchange='test_headers_exchange', queue=queue_name, routing_key='', arguments=binding_keys) print(f' [*] Waiting for logs matching {str(binding_keys)}. To exit press CTRL+C') ``` 这段程序片段声明了一个临时独占队列,并将其与之前建立好的header交换机关联起来,同时指定了两个头部字段用于精确匹配(`x-match=all`)模式下所有传入消息都必须携带相同的`header_key:value`组合才能进入该队列。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

8一天不

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

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

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

打赏作者

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

抵扣说明:

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

余额充值