IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> RabbitMQ.交换机详解 -> 正文阅读

[Java知识库]RabbitMQ.交换机详解

一.交换机

1.Exchange

在RabbitMQ中,生产者发送消息不会直接将消息投递到队列中,而是先将消息投递到交换机中,在由交换机转发到具体的队列,队列再将消息以推送或者拉取方式给消费者进行消费

生产者将消息发送到Exchange,由Exchange再路由到一个或多个队列中

2.路由键( Routingkey)

生产者将消息发送给交换机的时候,会指定RoutingKey指定路由规则。

3.绑定键(Bindi?ngKey)

通过绑定键将交换机与队列关联起来,这样RabbitMQ就知道如何正确地将消息路由到队列。

4.小结

生产者将消息发送给哪个Exchange是需要由RoutingKey决定的,生产者需要将Exchange与哪个队列绑定时需要由BindingKey决定的。

二.交换机类型

1.直连交换机:?Direct?exchange

直连交换机的路由算法非常简单:将消息推送到binding?key与该消息的routing?key相同的队列.

直连交换机X上绑定了两个队列。第一个队列绑定了绑定键orange,第二个队列有两个绑定键:black和green

在这种场景下,一个消息在布时指定了路由键为orange将会只被路由到队列Q1,路由键为black和green的消息都将被路由到队列Q2。其他的消息都将被丢失

同一个绑定键可以绑定到不同的队列上去,可以增加一个交换机X与队列Q2的绑定键,在这种情况下,直连交换机将会和广播交换机有着相同的行为,将消息推送到所有匹配的队列。一个路由键为black的消息将会同时被推送到队列Q1和Q2.

?

2.主题交换机:?Topic?exchange

直连交换机的缺点

直连交换机?grouting?key?方案非常简单,如果我们希望一条消息发送给多个队列,那么这个交换机需要绑定上非常多的?routing?key?.假设每个交换机上都绑定一维的?routing?key?连搜到各个队列上、那么消息的管理求会异常地困难。

?主题交换机的特点:

发送到主题交换机的消息不能有任意的?routing?key?,必须是由点号分开的一串单词,这些单词可以是任意的,但通常是与消息相关的一些特征

比如以下是几个有效的: routing key :" stock . usd . nyse "," nyse . vmw ”," quick . orange . rabblt ”, routing key 的单词可以有很多,最大限制是255 bytes .

?Topic 交换机的逻辑与 direct 交换机有点相似使用特定路由键发送的消息将被发送到所有使用匹配绑定键绑定的队列,然而,绑定键有两个特殊的情况:

①表示匹配任意一个单词

②表示匹配任意一个或多个单词

延申
当一个队列的绑定健是°#,它将会接收所有的消息,而不再考慮所接收消息的路由键

当一个队列的绑定键没有用到#和*时,它又像?direct?交换一样工作。

3.扇形交换机:?Fanout?exchange?

扇形交换机是最基本的交换机类型,它所能做的事悄非常简单广播消息。
扇形交换机会把能接收到的消息全部发送给绑定在自己身上的队列。因为广播不需要思考”,所以扇形交换机处理消息的速度也是所有的交换机类型里面最快的。

?4.首部交换机: Headers exchange?

首部交换机和扇形交换机都不界要路由键 routingKey 交换机时通过 Headers 头部来将消息映射到队列的,有点像 HTTP 的 Headers .
?Hash 结构中要求携带一个健×- match ”,这个键的 Value 可以是 any 或者 al ,这代表消息携带的 Hash 是需要全部匹 al ),还是仅四配一个健( any )就可以了。
相比直连交换机,首部交换机的优勢是匹配配的规则不被限定为字符串( string )而是 Object 类型。?

all :在发布消息时携带的所有 Entry 必须和绑定在队列上的所有 Entry 完全匹配
any :只要在发布消息时携带的有一对键值 headers 满足队列定义的多个参数 arguments 的其中一个就能匹配上,注意这里是键值对的院全匹配,只匹配到健了,值却不一样是不行的;

5.默认交换机

实上是一个由 RabbitMQ 预先声明好的名字为空字符申的直连交换机( direct exchange )·
它有一个特殊的属性使得它对于简单应用特别有用处:那就是每个新建队列( queue )都会自动綁定到认交换机上,綁定的路由键( routing key )名称与队列名称相同。

三.代码演示

注意:交换机与列队绑定时,方法名不能与其他的重复?

1.直连

①.Provider

(1).DirectConfig

package com.zxy.provider.mq;

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.zxy.provider;

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,"Hello Wold");
        return  "yes";
    }

}

②.cunsumer

(1).DirectReceiverA

package com.zxy.consumer.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);
    }
}


(2).DirectReceiverB

package com.zxy.consumer.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 = "directQueueB")
@Slf4j
public class DirectReceiverB {
    @RabbitHandler
    public void process(String message){
        log.info("B接到"+message);
    }

}

(3).DirectReceiverC

package com.zxy.consumer.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 = "directQueueC")
@Slf4j
public class DirectReceiverC {
    @RabbitHandler
    public void process(String message){
        log.info("C接到"+message);
    }

}

2.主题

①.Provider

(1)TopicConfig

package com.zxy.provider.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

 
    @RequestMapping("/topicSend")
    public String topicSend(String routingKey){
        template.convertAndSend("topicExchange",routingKey," word");
        return "yes";
    }

②.consumer

(1).TopicReceiverA

package com.zxy.consumer.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 TopicReceiverA {
    @RabbitHandler
    public void process(String message){
        log.warn("A接到"+message);
    }

}

(2).TopicReceiverB

package com.zxy.consumer.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 = "topicQueueB")
@Slf4j
public class TopicReceiverB {
    @RabbitHandler
    public void process(String message){
        log.warn("B接到"+message);
    }

}

(3).TopicReceiverC

package com.zxy.consumer.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 = "topicQueueC")
@Slf4j
public class TopicReceiverC {
    @RabbitHandler
    public void process(String message){
        log.warn("C接到"+message);
    }
}

3.扇形

①.provider

(1).FanoutConfig

package com.zxy.provider.mq;
 
 
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
@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");
    }
 
    /**
     * 进行交换机和队列的绑定,设置bindingkey
     *
     */
    @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

@RequestMapping("/fanoutSend")
    public String fanoutSend(){
        template.convertAndSend("topicExchange","null"," word me");
        return "yes";
    }

②.consumer

(1).FanoutReceiverA

package com.zxy.consumer.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 FanoutReceiverA {
 
 
 
    @RabbitHandler
    public void process(String message){
        log.info("C接到"+message);
 
    }
 
 
}

(2).FanoutReceiverB

package com.zxy.consumer.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 = "fanoutQueueB")
@Slf4j
public class FanoutReceiverB {
 
 
 
    @RabbitHandler
    public void process(String message){
        log.info("C接到"+message);
 
    }
 
 
}

(3).FanoutReceiverC

package com.zxy.consumer.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 = "directQueueC")
@Slf4j
public class FanoutReceiverC {
 
 
 
    @RabbitHandler
    public void process(String message){
        log.info("C接到"+message);
 
    }
 
 
}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-02-28 15:14:49  更:2022-02-28 15:19:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:37:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码