RabbitMQ

1.RabbitMQ

1.1.安装:

地址:https://www.cnblogs.com/cqyp/p/13463302.html

1.2.五种消息模型

1.2.1.基本模式

P(producer/ publisher):生产者,一个发送消息的用户应用程序。

C(consumer):消费者,监听队列,如果有关于自己的消息,就立即消费。

队列(红色区域):消息的暂存区

生产者将消息发送到队列,消费者从队列中获取消息,队列是存储消息的缓冲区。

1.2.2.work消息模式

此模式,一个消息只能被一个消费者获取。多个消费者监听一个队列,当消费者c1获取了消息,但是还没执行完成时,消息队列中有了新的消息,防止堆积,消费者c2就会消费此消息。

1.3.订阅模式

1.3.1.订阅模式分类

1、1个生产者,多个消费者

2、每一个消费者都有自己的一个队列

3、生产者没有将消息直接发送到队列,而是发送到了交换机(X)

4、每个队列都要绑定到交换机

5、生产者发送的消息,经过交换机到达队列,实现一个消息被多个消费者获取的目的

Exchange类型有以下几种:

Fanout:广播,将消息交给所有绑定到交换机的队列

Direct:定向,把消息交给符合指定routing key 的队列 

Topic:通配符,把消息交给符合routing pattern(路由模式) 的队列

1.3.2.订阅模型-Fanout

流程图和上面的一致

消息发送流程:

  • 1) 可以有多个消费者
  • 2) 每个消费者有自己的queue(队列)
  • 3) 每个队列都要绑定到Exchange(交换机)
  • 4) 生产者发送的消息,只能发送到交换机,交换机来决定要发给哪个队列,生产者无法决定。
  • 5) 交换机把消息发送给绑定过的所有队列
  • 6) 队列的消费者都能拿到消息。实现一条消息被多个消费者消费

1.3.3.订阅模型-Direct

P:生产者,向Exchange发送消息,发送消息时,会指定一个routing key。

X:Exchange(交换机),接收生产者的消息,然后把消息递交给 与routing key完全匹配的队列

C1:消费者,其所在队列指定了需要routing key 为 error 的消息

C2:消费者,其所在队列指定了需要routing key 为 info、error、warning 的消息

1.3.4.订阅模型-Topic

Topic类型的ExchangeDirect相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符

`#`:匹配一个或多个词    :          `audit.#`:能够匹配`audit.irs.corporate` 或者 `audit.irs`

`*`:匹配不多不少恰好1个词  :        `audit.*`:只能匹配`audit.irs`

2.RabbitMQ整合springBoot

2.1.环境搭建

添加依赖

<dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
</dependencies>

2.2.配置

2.2.1.配置application.yml

server:
  port: 44000
spring:
  application:
    name: test-rabbitmq-producer
  rabbitmq:
    host: 192.168.157.129
    port: 5672
    username: guest
    password: guest
    virtualHost: /

2.2.2.定义RabbitConfifig类,配置Exchange、Queue、及绑定交换机。

@Configuration
public class RabbitmqConfig {
    //队列
    public static final String QUEUE_INFORM_EMAIL = "queue_inform_email";
    public static final String QUEUE_INFORM_SMS = "queue_inform_sms";
    //交换机
    public static final String EXCHANGE_TOPICS_INFORM="exchange_topics_inform";
    //routingKey
    public static final String ROUTINGKEY_EMAIL = "inform.#.email.#";
    public static final String ROUTINGKEY_SMS = "inform.#.sms.#";

    //声明交换机
    @Bean(EXCHANGE_TOPICS_INFORM)
    public Exchange EXCHANGE_TOPICS_INFORM() {
        //durable(true) 持久化,mq重启之后交换机还在
        return ExchangeBuilder.topicExchange(EXCHANGE_TOPICS_INFORM).durable(true).build();
    }

    //声明队列
    @Bean(QUEUE_INFORM_EMAIL)
    public Queue QUEUE_INFORM_EMAIL() {
        return new Queue(QUEUE_INFORM_EMAIL);
    }
    @Bean(QUEUE_INFORM_SMS)
    public Queue QUEUE_INFORM_SMS() {
        return new Queue(QUEUE_INFORM_SMS);
    }

    //队列绑定交换机
    @Bean
    public Binding BINDING_QUEUE_INFORM_EMAIL (@Qualifier(QUEUE_INFORM_EMAIL) Queue queue,
                                               @Qualifier(EXCHANGE_TOPICS_INFORM) Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTINGKEY_EMAIL).noargs();
    }
    @Bean
    public Binding BINDING_ROUTINGKEY_SMS(@Qualifier(QUEUE_INFORM_SMS) Queue queue,
                                          @Qualifier(EXCHANGE_TOPICS_INFORM) Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTINGKEY_SMS).noargs();
    }
}


2.3.生产者

2.3.1.发送消息测试

@SpringBootTest
@RunWith(SpringRunner.class)
public class Product05_springboot {

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Test
    public void testSendEmail() {
        /**
         * 发送消息
         * 参数:
         *    1. 交换机
         *    2. routingKey
         *    3. 消息内容
         */
        String message = "send email message to user";
        rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE_TOPICS_INFORM,"inform.email",message);
    }
}

2.4.消费者

导入依赖,配置yml文件,编写配置类和上面一样;

2.4.1.接收消息测试

@Component
public class ReceiveHandler {

    @RabbitListener(queues = {RabbitmqConfig.QUEUE_INFORM_EMAIL})
    public void send_email(String msg, Message message, Channel channel) {
        System.out.println("接受的消息:" + msg);
    }
}
posted @ 2020-08-11 09:22  撑起一片阳光  阅读(149)  评论(0编辑  收藏  举报