RabbitMQ 消息中间件总结

RabbitMQ 是实现高级消息队列协议(AMQP:Advanced Message Queue Protocol)的开源代理软件,也称为面向消息的中间件。支持多种操作系统、多种编程语言。RabbitMQ 服务器使用 Erlang 语言编写,其集群和故障转移是构建在开放电信平台框架上的。

AMQP 是一个面向消息中间件的开放式应用层协议。定义消息方向、消息队列、消息路由、可靠性、安全性等特性。要求消息的提供者和客户端接收者的行为要实现对不同供应商可以用相同的方式(FTP/HTTP/SMTP等)进行互相操作。以往的JMS,主要是建立在 API级别,建立标准化的程序间的互操作性。而 AMQP 是一个线路级协议。描述的是通过网络发送的数据传输格式,任何符合该数据格式的消息发送和接收工具都能互相兼容和进行操作,这样就可以实现跨技术平台的架构方案。

一、基本概念


【1】Broker:消息队列服务器的实体,负责接收生产者的消息,然后将消息发送到消息接受者或者其他 Broker。
【2】Exchange:消息交换机,消息第一个到达的地方,消息通过它指定的路由规则,分发到不同的消息队列中去。
【3】Queue:消息队列,消息通过发送和路由之后最终到达的地方,到达 Queue 的消息即进入逻辑上等待消费的状态。每个消息都会被发送到一个或多个队列。
【4】Binding:绑定,它的作用是把 Exchange 和 Queue 按照路由规则绑定起来(虚拟连接)。
【5】Routing Key:路由关键字,Exchange 根据这个关键字进行消息投递。
【6】Virtual host:虚拟主机,它是对 Broker 的虚拟划分,将消费者、生产者和他们依赖的 AMQP 相关结构进行隔离,一般都是为了安全考虑。比如,我们可以在一个Broker中设置多个虚拟主机,对不同用户进行权限管理。
【7】Connection:连接,代表生产者、消费者、Broker 之间进行通信的物理网络。
【8】Channel:消息通道,用户连接生产者与消费者的逻辑结构。在客户端的每个连接里,可建立多个 Channel,每个 Channel,每个 Channel 代表一个会话任务,通过 Channel 可以隔离同一连接中的不同交互内容。
【9】Producer:消息生产者,制造消息并发送消息的程序。
【10】Consumer:消息消费者,接收消息并处理消息的程序。

二、消息传递到队列的过程


【1】客户端连接到消息队列服务器,打开一个 Channel。
【2】客户端声明一个 Exchange,并设置相关属性。
【3】客户端声明一个 Queue,并设置相关属性。
【4】客户端使用 Routing Key,在Exchange 和 Queue 之间建立好绑定关系。
【5】客户端投递消息到 Exchange。
【6】Exchange 接收到消息后,根据消息的 Key 和已经设置的 Binding,进行消息路由,将消息传递到一个或多个 Queue 里。

三、Exchange 三种类型


【1】Direct 交换机:完全根据 Key 进行投递。比如,绑定时设置了 Routing Key 为 abc,那么客户端提交的消息,只有设置了 Key 为 abc 的才会被投递到队列。
【2】Topic 交换机:对 Key 进行模式匹配后进行投递,可以使用符号#匹配一个或多个词,符号*匹配正好一个词。比如,abc.#匹配abc.efg.dwg,abc.*只匹配类似 abc.efg。
【3】Fanout 交换机:不需要任何 Key,它采用广播模式,一个消息进来时,投递到与该交换机绑定的所有队列。

四、RabbitMQ 持久化策略


为了数据安全考虑,大多数情况下都会选择持久化,也就是将数据写到磁盘上。消息持久化包括以下3个部分:
【1】Exchange 持久化,在声明时指定 durable => 1;
【2】Queue 持久化,在声明时指定 durable => 1;
【3】消息持久化,在投递时指定 delivery_mode => 2(1是非持久化)
如果 Exchange 和 Queue 都是持久化的,那么他们之间的 Binding 也是持久化的,如果 Exchange 和 Queue 两者之间有一个是持久化的,一个是非持久化的。就不允许建立绑定。

五、RabbitMQ 管理


我们可以直接通过访问配置文件进行管理,也可以通过访问 Web 进行管理,我们主要介绍通过 Web 进行管理。
【1】配置完环境之后,在 cmd 窗口执行 rabbitmq-plugins enable rabbitmq_management 命令,开启 Web 管理插件。
 
【2】在浏览器中访问 http://localhost:15672/ 并使用默认用户 guest 登录,密码也为 guest。可以看到如下管理页面:

从图中能够看到之前提到的一些基本概念,比如 Connections、Channel、Exchanges、Queues 等。可以在 Admin 中添加用户和修改用户权限等操作:

Tags 标签是 RabbitMQ 中的角色分类,共有下面几种:
  ●  none:不能访问 management plugin;
  ●  management:用户可以通过 AMQP 做的任何事外加入下内容:
      ■  列出自己可以通过 AMQP 登入的 virtual hosts;
      ■  查看自己 virtual hosts 中 queues、exchanges 和 bindings;
      ■  查看和关闭自己的 channels 和 connections;
      ■  查看有关自己的 virtual hosts 的全局统计信息,包含其它用户在这些 virtual hosts 中的活动。
  ●  policymarker:management 可以做的任何事情外加如下内容:
      ■  查看、创建、删除自己的 virtual hosts 所属的 policies 和 parameters;
  ●  monitoring:management 可以做的任何事外加如下内容:
      ■  列出所有 virtual hosts,包括它们不能登录的 virtual hosts;
      ■  查看其它用户 connections 和 channels;
      ■  查看节点级别的数据,如 clustering 和 memory 的使用情况。
      ■  查看真正的关于所有 virtual hosts 的全局统计信息;
  ●  administrator:policymarker 和 monitoring 可以做的任何事外加如下内容:
      ■  创建和删除 virtual hosts;
      ■  查看、创建和删除 users;
      ■  查看、创建和删除 permissions;
      ■  关闭其它用户的 connections;

六、快速入门


通过Spring Boot 应用整合 RabbitMQ,实现一个简单的发送、接收消息的例子。在Spring Boot 中添加 AMQP 的 Starter 即可。
【1】创建一个 SpringBoot 工程,命名为 rabbitmq-hello;
【2】在 pom.xml 中引入如下依赖内容:

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

【3】在 application.yml 中配置关于 RabbitMQ 的连接和用户信息:

spring:
  application:
    name: rabbitmq-hello
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

【4】创建消息生产者 Sender,通过注入 AmqpTemplate 接口的实例来实现消息的发送,AmqpTemplate 接口定义了一套针对 AMQP 协议的基本操作。在 SpringBoot 中会根据配置注入其具体实现。在该生产者汇总,我们会产生一个字符串,并向队列名为 hello 中发送消息。

@Component
public class Sender {
    @Autowired
    private AmqpTemplate rabbitTemp;

    public void send(){
        String context = "hello "+new Date();
        System.out.println("Sender : " + context);
        this.rabbitTemp.convertAndSend("hello",context);
    }
}

【5】创建消费者 Receiver,通过 @RabbitListener 注解定义该类对 hello 队列的监听,并用 @RabbitHandler 注解来指定对消息的处理方法。

@Component
@RabbitListener(queues = "hello")
public class Receiver {
    @RabbitHandler
    public void process(String hello){
        System.out.println("Receviver:"+hello);
    }
}

【6】创建 RabbitMQ 的配置类 RabbitConfig,用来配置队列,交换器、路由等高级特性。

@Configuration
public class helloQueue {


----关注公众号,获取更多内容----

posted @ 2020-11-18 17:38  Java程序员进阶  阅读(81)  评论(0编辑  收藏  举报