RabbitMQ队列模型

模型定义

  • 生产者(Producer):发送消息到队列的模块,可以理解为消息的提供者
  • 队列(Queue):存储消息的一段空间,作为消息的缓存模块;
  • 消费者(Consumer):从队列中接受消息的模块,可以理解为消息的处理者
  • 交换机(Exchange):消息不直接发到队列,首先发到 Exchange 模块,再根据路由规则转发到定制化的队列。

队列模型

  • 简单队列
  • 工作队列
  • 发布/订阅队列
  • 路由队列
  • 主题队列

简单队列

在简单队列模型中,只有一个生产者、一个消息队列、一个消费者。
RabbitMQ队列模型_第1张图片

  • 优点是不需要配置复杂的路由规则
  • 缺点是只支持一对一通信
  • 在大多数场景中一般不会使用这种队列

工作队列(Work Queue)

在工作队列模型中,一个生产者,拥有向多个消息消费者发送消息的能力,但是一条消息只能被一个消费者消费。
如何保证详细不被重复消费,在使用消息队列时也是需要考虑的问题

RabbitMQ队列模型_第2张图片

  • 应用场景:需要将流量打散到多个消费者模块的场景,也就是削峰
  • 例如美团点餐中,某一时段点餐高峰,电商秒杀等,瞬时流量很大的应用

发布/订阅队列(Publish/Subscribe)

RabbitMQ队列模型_第3张图片

  • 在发布/订阅队列模型中,生产者只能向交换机发送消息,交换机绑定了多个队列,
  • 所有绑定该交换机的队列都会收到交换机中的所有消息。

交换机存在四种路由方式:

  • direct
  • topic
  • headers
  • fanout-广播

发布/订阅模型是非常常见的队列模型
例如上篇文章中的注册流程中,一个用户的注册请求需要往短信服务和邮箱服务发送消息,可以使用该模型。

路由队列(Routing)

路由队列也是在发布/订阅队列模型中的一种,只是交换机的路由方式不一样,交换机的路由方式为direct模式
RabbitMQ队列模型_第4张图片

  • 在路由队列模型中,生产者将消息发送到 direct 模式的交换机,交换机和队列绑定的时候限制了路由 Key。
  • 当生产者发送一条消息的时候,会指定一条路由 Key,这条消息只会发送到对应的队列中
  • 每个队列都会绑定一个key,只有发送消息的key和绑定key相同的队列才能收到消息
@Configuration
public class RabbitmqDirectConfig {

    /**
     * 队列 queue
     */
    private static final String QUEUE_DIRECT_01 = "queue_direct01";
    private static final String QUEUE_DIRECT_02 = "queue_direct02";

    /**
     * 交换机 exchange
     */
    private static final String DIRECT_EXCHANGE = "directExchange";

    /**
     * 路由键 routingkey #表示0或多个单词,*表示一个单词
     */
    private static final String QUEUE_RED = "queue.red";
    private static final String QUEUE_GREEN = "queue.green";

    @Bean
    public Queue queueDirect01() {
        return new Queue(QUEUE_DIRECT_01);
    }

    @Bean
    public Queue queueDirect02() {
        return new Queue(QUEUE_DIRECT_02);
    }

    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange(DIRECT_EXCHANGE);
    }

    @Bean
    public Binding bindingDirectRed() {
        return BindingBuilder.bind(queueDirect01()).to(directExchange()).with(QUEUE_RED);
    }

    @Bean
    public Binding bindingDirectGreen() {
        return BindingBuilder.bind(queueDirect02()).to(directExchange()).with(QUEUE_GREEN);
    }

}

路由队列的优势是能够定制化发送消息,消费者选择性收听消息,适合灵活变通的应用场景。

主题队列(Topics)

主题队列也是在发布/订阅队列模型中的一种,只是交换机的路由方式不一样,交换机的路由方式为topic模式
RabbitMQ队列模型_第5张图片

  • 在主题队列模型中,实际上是基于路由队列的定制化配置,支持了key的通配符匹配
  • 简单理解就是正则表达式+路由key。
  • 例如*.queue只能匹配到a.queue类似的key,但是queue.#可以匹配到queue.a或者queue.a.b类似的key。
  • 应用场景与路由队列相同。
/**
 * Title: RabbitmqTopicConfig
 * Description: Topic模式常用
 */
@Configuration
public class RabbitmqTopicConfig {

    /**
     * 队列 queue
     */
    private static final String QUEUE_TOPIC_01 = "queue_topic01";
    private static final String QUEUE_TOPIC_02 = "queue_topic02";

    /**
     * 交换机 exchange
     */
    private static final String TOPIC_EXCHANGE = "topicExchange";

    /**
     * 路由键 routingkey
     * #表示匹配0或多个单词
     * *表示匹配一个单词
     */
    private static final String ROUTINGKEY_01 = "#.queue.#";
    private static final String ROUTINGKEY_02 = "*.queue.#";

    @Bean
    public Queue queueTopic01() {
        return new Queue(QUEUE_TOPIC_01);
    }

    @Bean
    public Queue queueTopic02() {
        return new Queue(QUEUE_TOPIC_02);
    }

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

    @Bean
    public Binding bindingTopic01() {
        return BindingBuilder.bind(queueTopic01()).to(topicExchange()).with(ROUTINGKEY_01);
    }

    @Bean
    public Binding bindingTopic02() {
        return BindingBuilder.bind(queueTopic02()).to(topicExchange()).with(ROUTINGKEY_02);
    }

}

你可能感兴趣的:(消息队列,队列,交换机,rabbitmq)