Rabbitmq 不同交换机类型如何使用,一文教会你

1、Rabbitmq组件介绍

消息队列有三个核心要素: 消息生产者、消息队列、消息消费者

1)、生产者(Producer):发送消息的应用;(java程序,也可能是别的语言写的程序)

2)、消费者(Consumer):接收消息的应用;(java程序,也可能是别的语言写的程序)

3)、代理(Broker):就是消息服务器,RabbitMQ Server就是Message Broker;

4)、连接(Connection):连接RabbitMQ服务器的TCP长连接;

5)、信道(Channel):连接中的一个虚拟通道,消息队列发送或者接收消息时,都是通过信道进行的;

6)、虚拟主机(Virtual host):一个虚拟分组,在代码中就是一个字符串,当多个不同的用户使用同一个RabbitMQ服务时,可以划分出多个Virtual host,每个用户在自己的Virtual host创建exchange/queue等;(分类比较清晰、相互隔离)

7)、交换机(Exchange):交换机负责从生产者接收消息,并根据交换机类型分发到对应的消息队列中,起到一个路由的作用;

8)、路由键(Routing Key):交换机根据路由键来决定消息分发到哪个队列,路由键是消息的目的地址;

9)、绑定(Binding):绑定是队列和交换机的一个关联连接(关联关系);

10)、队列(Queue):存储消息的缓存;

11)、消息(Message):由生产者通过RabbitMQ发送给消费者的信息;(消息可以任何数据,字符串、user对象,json串等等)。

2、引入依赖和添加配置(application.yml)
2.1、引入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
    <version>3.1.2</version>
</dependency>
2.2、配置信息
spring:
  rabbitmq:
    host: 192.168.30.88
    port: 5672
    username: admin
    password: admin
    virtual-host: test   # 指定虚拟主机
3、交换机的类型与具体编码实现
3.1、交换机类型

1)、Fanout Exchange(扇形)
2)、Direct Exchange(直连)
3)、Topic Exchange(主题)
4)、Headers Exchange(头部) 

3.2、Fanout Exchange

         Fanout 扇形的,散开的; 扇形交换机投递消息到所有绑定的队列,不需要路由键,不需要进行路由键的匹配,相当于广播、群发。

 Fanout Exchange 配置代码实现

rabbit:
  fanout:
    exchangeName: exchange.fanout
    queueAName: queue.fanout.a
    queueBName: queue.fanout.b
@SpringBootConfiguration
@ConfigurationProperties(prefix = "rabbit.fanout")
@Data
public class RabbitConfigFanout {
    private String exchangeName;
    private String queueAName;
    private String queueBName;
    // 1、定义交换机,可以采用new的方式,也可以采用建造者模式
    @Bean
    public FanoutExchange fanoutExchange(){
        return ExchangeBuilder.fanoutExchange(exchangeName).build();
    }
    // 2、定义队列
    @Bean
    public Queue queueA(){
        return  QueueBuilder.durable(queueAName).build();
    }
    @Bean
    public Queue queueB(){
        return  QueueBuilder.durable(queueBName).build();
    }
    // 3、绑定交换机和对列
    @Bean
    public Binding bindingA(FanoutExchange exchange, Queue queueA){
        return BindingBuilder.bind(queueA).to(exchange);
    }
    @Bean
    public Binding bindingB(FanoutExchange exchange, Queue queueB){
        return BindingBuilder.bind(queueB).to(exchange);
    }
}

Fanout Exchange 生产者代码实现

@Autowired
private RabbitTemplate rabbitTemplate;
public void sendMessage(){
    String msg = "hello world!";
    Message message = new Message(msg.getBytes());
    // 向指定的交换机中发送message
    rabbitTemplate.convertAndSend("exchange.fanout", "", message);

}

Fanout Exchange 消费者代码实现

// 从两个队列中获取消息
@RabbitListener(queues = {"queue.fanout.a", "queue.fanout.b"})
public void rec(Message message){
    String msg = new String(message.getBody());
    System.out.println(msg);
}
3.3、Direct Exchange

        根据路由键精确匹配(一模一样)进行路由消息队列。  

 Direct Exchange 配置代码实现

rabbit:
  direct:
    exchangeName: exchange.direct
    queueAName: queue.direct.a
    queueBName: queue.direct.b
@SpringBootConfiguration
@ConfigurationProperties(prefix = "rabbit.direct")
@Data
public class RabbitConfigDirect {
    private String exchangeName;
    private String queueAName;
    private String queueBName;
    // 1、定义交换机
    @Bean
    public DirectExchange directExchange(){
        return ExchangeBuilder.directExchange(exchangeName).build();
    }
    // 2、定义队列
    @Bean
    public Queue queueA(){
        return  QueueBuilder.durable(queueAName).build();
    }
    @Bean
    public Queue queueB(){
        return  QueueBuilder.durable(queueBName).build();
    }
    // 3、通过精确路由key绑定交换机和对列
    @Bean
    public Binding bindingA(DirectExchange exchange, Queue queueA){
        return BindingBuilder.bind(queueA).to(exchange).with("error");
    }
    @Bean
    public Binding bindingB(DirectExchange exchange, Queue queueB){
        return BindingBuilder.bind(queueB).to(exchange).with("info");
    }
    @Bean
    public Binding bindingC(DirectExchange exchange, Queue queueB){
        return BindingBuilder.bind(queueB).to(exchange).with("error");
    }
    @Bean
    public Binding bindingD(DirectExchange exchange, Queue queueB){
        return BindingBuilder.bind(queueB).to(exchange).with("warning");
    }
}

Direct Exchange 生产者代码实现

@Autowired
private RabbitTemplate template;
public void sendMsg(){
    Message message = MessageBuilder.withBody("hello long".getBytes()).build();
    // 向指定的交换机和指定路由key发送message
    template.convertAndSend("exchange.direct", "error", message);
}

Direct Exchange 消费者代码实现

// 从两个队列中获取消息
@RabbitListener(queues = {"queue.direct.a"})
public void rec(Message message){
    String msg = new String(message.getBody());
    System.out.println(msg);
}
3.4、Topic Exchange

        通配符匹配,相当于模糊匹配;

1)、# 匹配多个单词,用来表示任意数量(零个或多个)单词;

2)、* 匹配一个单词(必须有一个,而且只有一个),用 . 隔开的为一个单词。

例如:

        aaa.# == aaa.queue.abc, aaa.queue.xyz.xxx

        aaa.* == aaa.queue, aaa.xyz

 

 Topic Exchange 配置代码实现

rabbit:
  topic:
    exchangeName: exchange.topic
    queueAName: queue.topic.a
    queueBName: queue.topic.b
@SpringBootConfiguration
@ConfigurationProperties(prefix = "rabbit.topic")
@Data
public class RabbitConfigTopic {
    private String exchangeName;
    private String queueAName;
    private String queueBName;
    // 1、定义交换机
    @Bean
    public TopicExchange topicExchange(){
        return ExchangeBuilder.topicExchange(exchangeName).build();
    }
    // 2、定义队列
    @Bean
    public Queue queueA(){
        return  QueueBuilder.durable(queueAName).build();
    }
    @Bean
    public Queue queueB(){
        return  QueueBuilder.durable(queueBName).build();
    }
    // 3、通过匹配路由key绑定交换机和对列
    @Bean
    public Binding bindingA(DirectExchange exchange, Queue queueA){
        return BindingBuilder.bind(queueA).to(exchange).with("*.orange.*");
    }
    @Bean
    public Binding bindingB(DirectExchange exchange, Queue queueB){
        return BindingBuilder.bind(queueB).to(exchange).with("*.*.rabbit");
    }
    @Bean
    public Binding bindingC(DirectExchange exchange, Queue queueB){
        return BindingBuilder.bind(queueB).to(exchange).with("lazy.#");
    }
}

Topic Exchange 生产者代码实现

@Autowired
private RabbitTemplate template;
public void sendMsg(){
    Message message = MessageBuilder.withBody("hello long".getBytes()).build();
    // 向指定的交换机和指定路由key发送message
    template.convertAndSend("exchange.topic", "lazy.a.b", message);
}

Topic Exchange 消费者代码实现

// 从两个队列中获取消息
@RabbitListener(queues = {"queue.topic.a"})
public void rec(Message message){
    String msg = new String(message.getBody());
    System.out.println(msg);
}
3.5、Headers Exchange

        基于消息内容中的headers属性进行匹配。

Headers Exchange 配置代码实现

rabbit:
  headers:
    exchangeName: exchange.headers
    queueAName: queue.headers.a
    queueBName: queue.headers.b

 

@SpringBootConfiguration
@Data
@ConfigurationProperties(prefix = "rabbit.headers")
public class RabbitConfigHeaders {
    private String exchangeName;
    private String queueAName;
    private String queueBName;
    // 1、定义交换机
    @Bean
    public HeadersExchange headersExchange(){
        return ExchangeBuilder.headersExchange(exchangeName).build();
    }
    // 2、定义队列
    @Bean
    public Queue queueA(){
        return QueueBuilder.durable(queueAName).build();
    }
    @Bean
    public Queue queueB(){
        return QueueBuilder.durable(queueBName).build();
    }
    // 3、绑定
    @Bean
    public Binding bindingA(HeadersExchange exchange, Queue queueA){
        Map<String, Object> headers = new HashMap<>();
        headers.put("type", "m");
        headers.put("status", 1);
        return BindingBuilder.bind(queueA).to(exchange).whereAll(headers).match();
    }
    @Bean
    public Binding bindingB(HeadersExchange exchange, Queue queueB){
        Map<String, Object> headers = new HashMap<>();
        headers.put("type", "s");
        headers.put("status", 0);
        return BindingBuilder.bind(queueB).to(exchange).whereAll(headers).match();
    }
}

Headers Exchange 生产者代码实现

@Autowired
private RabbitTemplate template;
public void sendMsg(){
    // 自定义消息属性
    MessageProperties messageProperties = new MessageProperties();
    messageProperties.setHeader("type", "m");
    messageProperties.setHeader("status", 1);
    Message message = MessageBuilder.withBody("hello long".getBytes()).andProperties(messageProperties).build();
    template.convertAndSend("exchange.headers", "", message);
}

Headers Exchange 消费者代码实现

// 从两个队列中获取消息
@RabbitListener(queues = {"queue.headers.a"})
public void rec(Message message){
    String msg = new String(message.getBody());
    System.out.println(msg);
}
4、总结

        本文详细介绍了Rabbitmq几种交换机的使用,后续更高级的用法将会在公众号上分享,关注下面微信公众号学习更多内容。

        本人是一个从小白自学计算机技术,对运维、后端、各种中间件技术、大数据等有一定的学习心得,想获取自学总结资料(pdf版本)或者希望共同学习,关注微信公众号:it自学社团。后台回复相应技术名称/技术点即可获得。(本人学习宗旨:学会了就要免费分享)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

知其_所以然

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

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

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

打赏作者

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

抵扣说明:

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

余额充值