RabbitMQ各Exchange适用场景

Default Exchange(默认交换机)

在首先创建一个 Queen 之后,RabbitMQ 会把这个 Queen 直接绑定到默认交换机上,并且使用 Queen 的名字作为 Routing Key。
因此,对外表现的效果就是,客户端向这个 Queen 直接投递消息,严格匹配。

// TODO 此处应该有代码

Direct exchange(直连交换机)

和 Default Exchange 类似,但灵活度更高,基于 AMQP 协议,可以由 Producer 或 Consumer 进行指定,伪代码如下:

//实现BeanPostProcessor类,使用Bean的生命周期函数
@Component
public class DirectRabbitConfig implements BeanPostProcessor {
    //这是创建交换机和队列用的 RabbitAdmin 对象
    @Resource
    private RabbitAdmin rabbitAdmin;
    
    //初始化 RabbitAdmin Bean
    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        // 只有设置为 true,spring 才会加载 RabbitAdmin 这个类
        rabbitAdmin.setAutoStartup(true);
        return rabbitAdmin;
    }
    
    //实例化bean后,也就是Bean的后置处理器
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        //向 RabbitMQ 声明创建 Exchange
        rabbitAdmin.declareExchange(rabbitmqDemoDirectExchange());
        //向 RabbitMQ 声明创建 Queen
        rabbitAdmin.declareQueue(rabbitmqDemoDirectQueue());
        return null;
    }
    /**
     * 声明一个 Queen Bean, 用于上面这个方法
     */
    @Bean
    public Queue rabbitmqDemoDirectQueue() {
        /**
         * 1、name:    队列名称
         * 2、durable: 是否持久化
         * 3、exclusive: 是否独享、排外的。如果设置为true,定义为排他队列。则只有创建者可以使用此队列。也就是private私有的。
         * 4、autoDelete: 是否自动删除。也就是临时队列。当最后一个消费者断开连接后,会自动删除。
         * */
        return new Queue(RabbitMQConfig.RABBITMQ_DEMO_TOPIC, true, false, false);
    }
    /**
     * 声明一个 DirectExchange Bean, 用于上面的上面这个方法
     */
    @Bean
    public DirectExchange rabbitmqDemoDirectExchange() {
        //Direct交换机
        return new DirectExchange(RabbitMQConfig.RABBITMQ_DEMO_DIRECT_EXCHANGE, true, false);
    }
    /**
     * 声明一个 Binding Bean, 用于把 Queen 和 Exchange 进行绑定
     * 并设置 RabbitMQConfig.RABBITMQ_DEMO_DIRECT_ROUTING 作为 Routing Key
     * 投递消息的时候可以使用这个 key 通过这个 Exchange 发送到这个 Queen 上
     */
    @Bean
    public Binding bindDirect() {
        //链式写法,绑定交换机和队列,并设置匹配键
        return BindingBuilder
                //绑定队列
                .bind(rabbitmqDemoDirectQueue())
                //到交换机
                .to(rabbitmqDemoDirectExchange())
                //并设置匹配键
                .with(RabbitMQConfig.RABBITMQ_DEMO_DIRECT_ROUTING);
    }
}

Fanout exchange(扇形交换机)

无需依靠 Routing Key,所有绑定到这种 Exchange 上的 Queen 都会收到投递,因此适合广播消息:

  • 大规模多用户在线(MMO)游戏可以使用它来处理排行榜更新等全局事件
  • 体育新闻网站可以用它来近乎实时地将比分更新分发给移动客户端
  • 分发系统使用它来广播各种状态和配置更新
  • 在群聊的时候,它被用来分发消息给参与群聊的用户。(AMQP 没有内置 presence 的概念,因此 XMPP 可能会是个更好的选择)

    // TODO 此处应该有配置 Bean 的代码和 Producer 的发送 demo

Topic Exchange(主题交换机)

Routing Key 支持单词匹配和全模糊匹配,缺德的地方在于匹配两点之间的内容,而 # 匹配所有,如routing..user只能匹配 routing.biz.user、routing.user.user、routing.car.user,而 routing.#.user 能匹配 routing.car.Chevrolet.Corvette.ZR1.user。
由于这种 Exchange 支持通配符的 Routing Key,因此在定义 Queen 和 Routing Key 的时候,要考虑对命名进行特征分组,如:

  • 懒得写了,反正就是以点为分隔符,对 Queen 和 Routing Key 做业务分组,投递的时候按照分组规则进行投递

Headers Exchange(头信息交换机)

Routing Key 是没用的,在初始化 Binding 时设置一些 map 进去,在投递消息时带上 map 中的一些元素或全部元素,就可以实现 Exchange 到 Queen 的投递了。这种方式较上一个,灵活性无疑更高了,支持复杂的 Binding,不过会不会太过复杂把新手都搞晕了,所以我不太建议用

// TODO 照例这里应该有代码,还是算了,想起来再写

参考链接1
参考链接2

你可能感兴趣的:(RabbitMQ各Exchange适用场景)