SpringCloud RabbitMQ介绍和使用(七)

RabbitMQ介绍

MQ全称为Message Queue,消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过 队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求

MQ的特点

MQ是消费-生产者模型的一个典型的代表,一端往消息队列中不断写入消息,而另一端则可以读取或者订阅队列中的消息。

使用场景

在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。

几个概念

  • Exchange:交换机,决定了消息路由规则;
  • Queue:消息队列;
  • Channel:进行消息读写的通道;
  • Bind:绑定了Queue和Exchange,意即为符合什么样路由规则的消息,将会放置入哪一个消息队列;

消息持久化

  • 将交换机置为可持久;
  • 将通道置为可持久
  • 将通道置为可持久

当我们“生产”了一条可持久化的消息,尝试中断MQ服务,启动消费者获取消息,消息依然能够恢复。相反,则抛出异常。

RabbitMQ的结构图如下:

在这里插入图片描述
概念说明:

  • Broker:简单来说就是消息队列服务器实体。
  • Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。
  • Queue:消息队列载体,每个消息都会被投入到一个或多个队列。
  • Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。
  • Routing Key:路由关键字,exchange根据这个关键字进行消息投递。
  • vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。
  • producer:消息生产者,就是投递消息的程序。
  • consumer:消息消费者,就是接受消息的程序。
  • channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。

消息队列的使用过程

  • 客户端连接到消息队列服务器,打开一个channel。
  • 客户端声明一个exchange,并设置相关属性。
  • 客户端声明一个queue,并设置相关属性。
  • 客户端使用routing key,在exchange和queue之间建立好绑定关系。
  • 客户端投递消息到exchange。

exchange接收到消息后,就根据消息的key和已经设置的binding,进行消息路由,将消息投递到一个或多个队列里。

exchange也有几个类型,完全根据key进行投递的叫做Direct(直接)交换机,例如,绑定时设置了routing key为”abc”,那么客户端提交的消息,只有设置了key为”abc”的才会投递到队列。对key进行模式匹配后进行投递的叫做Topic交换机,符号”#”匹配一个或多个词,符号””匹配正好一个词。例如”abc.#”匹配”abc.def.ghi”,”abc.”只匹配”abc.def”。还有一种不需要key的,叫做Fanout交换机,它采取广播模式,一个消息进来时,投递到与该交换机绑定的所有队列。

RabbitMQ支持消息的持久化,也就是数据写在磁盘上,为了数据安全考虑,我想大多数用户都会选择持久化。消息队列持久化包括3个部分:

  • exchange持久化,在声明时指定durable => 1
  • queue持久化,在声明时指定durable => 1
  • 消息持久化,在投递时指定delivery_mode => 2(1是非持久化)

如果exchange和queue都是持久化的,那么它们之间的binding也是持久化的。如果exchange和queue两者之间有一个持久化,一个非持久化,就不允许建立绑定。

基于Idea+Springboot2.0+SpringCloud Hoxton.SR3,rabbitmq使用
  • 在pom.xml引入依赖amqp
  • 配置application.yml
  • 创建消息接收者服务
  • 创建发送消息客户端

引入amqp依赖

		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>

配置appcation.yml

spring:
  rabbitmq:
    host: 192.168.99.100
    port: 5672
    username: guest
    password: guest

接下来创建接收信息服务

package com.example.order.message;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * 接受MQ消息
 * Created by Administrator
 * 2020/4/8  21:30
 */
@Component
@Slf4j
public class MqReceiver {

    //1.@RabbitListener(queues = "myQueue") 需要在rabbitMQ创建名字为myQueue消息队列
    //2.自动创建队列  @RabbitListener(queuesToDeclare = @Queue("myQueue"))
    //3.自动创建,Exchange和Queue绑定
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue("myQueue"),
            exchange = @Exchange("myExchange")

    ))
    public void process(String message){
        log.info("message :{}",message);
    }

    /**
     * 电子数码供应商服务,接收信息
     * @param message
     */
    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange("myOrderExchange"),
            key = "computer",
            value = @Queue("computerOrderQueue")
    ))
    public void processComputer(String message){
        log.info("computer MqReceiver: {}",message);
    }

    /**
     * 零食供应商服务,接收消息
     * @param message
     */
    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange("myOrderExchange"),
            key = "foods",
            value = @Queue("foodsOrderQueue")
    ))
    public void processFoots(String message){
        log.info("foods MqReceiver: {}",message);
    }
}

模拟客户端发送消息进行测试:

package com.example.order;

import org.junit.jupiter.api.Test;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.stereotype.Component;
import java.util.Date;

/**
 *发送消息
 *  Created by Administrator
 * 2020/4/8  21:38
 */
@Component
@SpringBootTest
public class MqSenderTest  {

    @Autowired
    private AmqpTemplate amqpTemplate;

    /**
     * 发送消息给接收方
     */
    @Test
    public void sendMessage(){
        amqpTemplate.convertAndSend("myQueue","now: "+new Date());
    }

    /**
     * 发送消息给电子数码服务接收方
     */
    @Test
    public void sendComputerMessage(){
        amqpTemplate.convertAndSend("myOrderExchange","computer","now:"+new Date());
    }

    /**
     * 发送消息给零食服务接收方
     */
    @Test
    public void sendFoodsMessages(){
        amqpTemplate.convertAndSend("myOrderExchange","foods","now: "+new Date());
    }
}

通过RabbitMQ的管理界面,查看Queues,已经有了三个队列都是自动创建,分别为computerOrderQueue,myQueue,foodsOrderQueue,并且绑定到Exchange中。

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值