一、消息中间件 1. 何为消息中间件 消息队列中间件:Message Queue Middleware,简称MQ,是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间的通信。 消息队列中间件一般有两种传递模式:点对点(P2P,Point-to-Point)模式和发布/订阅(Pub/Sub)模式。 (1)点对点模式:基于队列,消息生产者发送消息到队列,消息消费者从队列中接收消息。 (2)发布/订阅模式:消息发布者将消息发布到某个主题,而消息订阅者则从主题中订阅消息。发布/订阅模式在消息的一对多广播时采用。(主题相当于消息传递的中介) 消息中间件适用于需要可靠的数据传送的分布式环境。 如上图,消息中间件负责处理网络通信,如果网络连接不可用,消息中间件会存储消息,直到连接变得可用,再将消息转发给应用程序B。 目前比较主流的开源消息中间件主要有:RabbitMQ、Kafka、ActiveMQ、RocketMQ等。 2. 消息中间件有何用处 消息中间件在分布式系统中的作用主要有:解耦、冗余(存储)、扩展性、削峰、可恢复性、顺序保证、缓冲、异步通信,等等,在不同的应用场景下展现的作用不同。 二、AMQP AMQP:Advanced Message Queuing Protocol,高级消息队列协议。AMQP 是应用层协议的一个开放标准,用于解决众多消息中间件的需求和拓扑结构问题。它为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。 1. 分层 AMQP 协议包括三层: (1)Module Layer:位于协议最高层,主要定义了一些供客户端调用的命令,客户端可以利用这些命令实现自己的业务逻辑。 (2)Session Layer:位于中间层,主要负责将客户端的命令发送给服务器,再将服务端的应答返回给客户端,主要为客户端与服务器之间的通信提供可靠性同步机制和错误处理。 (3)Transport Layer:位于最底层,主要传输二进制数据流,提供帧的处理、信道复用、错误检测和数据表示等。 从 low-level 举例来说,AMQP 本身是应用层的协议,其填充于 TCP 协议层的数据部分。而从 high-level 来说,AMQP 是通过协议命令进行交互的。AMQP 协议可以看作一系列结构化命令的集合,这里的命令代表一种操作,类似于 HTTP 中的方法(GET、POST、PUT、DELETE 等)。 2. 流转过程 (1)生产者流转过程 (2)消费者流转过程
三、RabbitMQ 1. 简介 RabbitMQ 是采用 Erlang 语言实现 AMQP 的消息中间件,它最初起源于金融系统,用于在分布式系统中存储转发消息。 2. 特点 (1)可靠性:持久化、传输确认、发布确认... (2)灵活的路由: 在消息进入队列之前,通过交换器来路由消息。对于典型的路由功能,RabbitMQ 已经提供了一些内置的交换器来实现。针对更复杂的路由功能,可以将多个交换器绑定在一起,也可以通过插件机制来实现自己的交换器。 (3)扩展性:多个 RabbitMQ 节点可以组成一个集群。动态扩展集群。 (4)高可用性:队列可以在集群中的机器上设置镜像,使得在部分节点出现问题的情况下队列仍然可用。 (5)多种协议:RabbitMQ 除了原生支持 AMQP 协议,还支持 STOMP、MQTT 等多种消息中间件协议。 (6)多种语言客户端 (7)管理界面 (8)插件机制:RabbitMQ 提供了许多插件,以实现从多方面进行扩展,当然也可以编写自己的插件。 3. 模型架构 RabbitMQ 整体上是一个生产者与消费者模型,主要负责接收、存储和转发消息。从计算机术语层面来说,RabbitMQ 模型更像是一种交换机模型。 RabbitMQ 的整体模型架构大概如下: 4. 基础概念解析 (1)Message:消息。消息一般可以包含2个部分 — 消息体和标签(Label)。消息的标签用来表述这条消息,比如一个交换器的名称和一个路由键。 (2)Producer:生产者,就是投递消息的一方。 (3)Consumer:消费者,就是接收消息的一方。消费者最终只得到消息的消息体,消息的标签在消息路由过程中被丢弃(消息标签只用于消息路由),所以消费者并不知道消息的生产者是谁,当然也不需要知道。 (4)Broker:消息中间件的服务节点。对于 RabbitMQ 来说,一个 RabbitMQ Broker 可以简单地看作一个 RabbitMQ 服务节点,或者 RabbitMQ 服务实例。 (5)Exchange:交换器。生产者将消息发送到 Exchange,由交换器将消息路由到一个或者多个队列中。如果路由不到,或许会返回给生产者,或许直接丢弃。 RabbitMQ 中的交换器有四种常用类型,不同的类型有着不同的路由策略。 <1>fanout:它会把所有发送到该交换器的消息路由到所有与该交换器绑定的队列中。无视RoutingKey。 <2>direct:它会把消息路由到那些 BindingKey 和 RoutingKey 完全匹配的队列中。 <3>topic:将消息路由到 BindingKey 和 RoutingKey 相匹配的队列中,匹配规则如下: RoutingKey 为一个点号“.”分隔的字符串(被点号“.”分隔开的每一段独立的字符串称为一个单词),如“com.rabbitmq.client”、“java.util.concurrent”、“com.hidden.client”; BindingKey 和 RoutingKey 一样也是点号“.”分隔的字符串; BindingKey 中可以存在两种特殊字符串“*”和“#”,用于做模糊匹配,其中“#”用于匹配一个单词,“#”用于匹配多规格单词(可以是零个)。 <4>headers:不依赖于路由键的匹配规则来路由消息,而是根据发送的消息内容中的 headers 属性进行匹配。headers 类型的交换器性能会很差,而且也不实用。 (6)Queue:队列,是 RabbitMQ 的内部对象,用于存储消息。在 RabbitMQ 中,消息都只能存储在队列中。 多个消费者可以订阅同一个队列,这时队列中的消息会被平均分摊(Round-Robin,即轮询)给多个消费者进行处理,而不是每个消费者都收到所有的消息并处理。 (7)BindingKey:绑定键。RabbitMQ 中通过绑定将交换器与队列关联起来,在绑定的时候一般会指定一个绑定键,这样 RabbitMQ 就知道如何正确地将消息路由到队列了。 (8)RoutingKey:路由键。生产者将消息发给交换器的时候,一般会指定一个 RoutingKey,用来指定这个消息的路由规则,而这个 RoutingKey 需要与交换器类型和绑定键(BindingKey)联合使用才能最终生效。 在交换器类型和绑定键(BindingKey)固定的情况下,生产者可以在发送消息给交换器时,通过指定 RoutingKey 来决定消息流向哪里。 消息从生产到消费的整个流程如下: 注:BindingKey 和 RoutingKey 本质上是同一个东西,就是负责将交换器与队列进行关联的,只是在绑定交换器与队列时叫 BindingKey,在路由消息时叫 RoutingKey。 5. 客户端与RabbitMQ的连接 Connection:生产者/消费者与 RabbitMQ Broker 之间的 TCP 连接。 Channel:AMQP 信道。每个信道都会被指派一个唯一的 ID。信道是建立在 Connection 之上的虚拟连接,RabbitMQ 处理的每条 AMQP 指令都是通过信道完成的。 RabbitMQ 采用类似 NIO(Non-blocking I/O)的做法,选择 TCP 连接复用,多个信道复用一个 TCP 连接,不仅可以减少性能开销,同时也便于管理。但当信道本身的流量很大时,多个信道复用一个 TCP 连接就会产生性能瓶颈,此时就需要开辟多个 TCP 连接。 6. 运转流程 生产者发送消息的过程 (1)生产者连接到 RabbitMQ Broker,建立一个 TCP 连接(Connection),开启一个信道(Channel)。 (2)生产者声明一个交换器(Exchange),并设置相关属性,比如交换器类型、是否持久化等。 (3)生产者声明一个队列(queue)并设置相关属性,比如是否排他、是否持久化、是否自动删除等。 (4)生产者通过绑定键(BindingKey)将交换器和队列绑定起来。 (5)生产者发送消息至 RabbitMQ Broker,其中包含交换器(Exchange)、路由键(RoutingKey)等信息。 (6)相应的交换器(Exchange)根据接收到的路由键(RoutingKey)查找相匹配的队列。 (7)如果找到,则将从生产者发送过来的消息存入相应的队列中。 (8)如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者。 (9)关闭信道。 (10)关闭TCP连接。 消费者接收消息的过程 (1)消费者连接到 RabbitMQ Broker,建立一个连接(Connection),开启一个信道(Channel)。 (2)消费者向 RabbitMQ Broker 请求消费相应队列中的消息,可能会设置相应的回调函数,以及做一些准备工作。 (3)等待 RabbitMQ Broker 回应并投递相应队列中的消息,消费者接收消息。 (4)消费者确认(ack)接收到的消息。 (5)RabbitMQ 从队列中删除相应已经被确认的消息。 (6)关闭信道。 (7)关闭连接。 四、单节点 RabbitMQ 安装 1. 安装 Erlang 安装 RabbitMQ 之前需要先安装 Erlang。注意 Erlang 和 RabbitMQ 之间版本号的对应关系,先到 RabbitMQ 官网看一下安装的 RabbitMQ 版本对 Erlang 版本的要求。 (1)安装Erlang的依赖包:
yum -y install make gcc gcc-c++ kernel-devel m4 ncurses-devel openssl-devel unixODBC-devel(2)官网下载Erlang:http://www.erlang.org/downloads,这里下载版本:23.2 解压,编译,安装:(这里安装至 /usr/local/erlang)
tar -zxvf otp_src_23.2.tar.gz cd otp_src_23.2 ./configure --prefix=/usr/local/erlang --without-javac make make install(3)修改配置文件/etc/profile,添加环境变量:
ERLANG_HOME=/usr/local/erlang export PATH=$PATH:$ERLANG_HOME/bin export ERLANG_HOME使配置文件生效:
source /etc/profile(4)验证 Erlang 是否安装成功: 2. 安装 RabbitMQ (1)官网下载:http://www.rabbitmq.com/releases/rabbitmq-server/,这里下载3.9.3版本。 解压即可使用:(这里解压至 /usr/local/)
xz -d rabbitmq-server-generic-unix-3.9.3.tar.xz tar -xvf rabbitmq-server-generic-unix-3.9.3.tar(2)修改配置文件:
export PATH=$PATH:/usr/local/rabbitmq_server-3.9.3/sbin export RABBITMQ_HOME=/usr/local/rabbitmq_server-3.9.3使配置文件生效:
source /etc/profile3. 运行 RabbitMQ (1)运行 RabbitMQ:
rabbitmq-server查看是否正常启动:
rabbitmqctl status(仅为部分截图) 输出可以看到当前 RabbitMQ 的数据存储目录、配置文件、使用内存量等信息。 查看集群状态:
rabbitmqctl cluster_status(仅为部分截图) 输出可以看到集群名称、集群节点组成等信息。 (2)创建root用户:
rabbitmqctl add_user root为root用户设置所有权限:
rabbitmqctl set_permissions -p / root ".*" ".*" ".*"为root用户设置管理员角色:
rabbitmqctl set_user_tags root administratorRabbitMQ 默认用户:guest,只能用于本地访问。 (3)开放端口:
firewall-cmd --zone=public --add-port=5672/tcp --permanent重启防火墙:
firewall-cmd --reload查看是否开放成功:
firewall-cmd --zone=public --query-port=5672/tcpRabbitMQ 默认运行端口:5672。 4. 访问 RabbitMQ 管理后台 (1)开启管理后台插件
rabbitmq-plugins enable rabbitmq_management管理后台默认使用端口:15672 (2)开放端口:
firewall-cmd --zone=public --add-port=15672/tcp --permanent重启防火墙:
firewall-cmd --reload查看是否开放成功:
firewall-cmd --zone=public --query-port=15672/tcp(3)创建管理后台用户
rabbitmqctl add_user admin admin1234 rabbitmqctl set_user_tags admin administrator(4)浏览器访问管理后台 http://{ip}:15672
安装参考: https://blog.csdn.net/junxieshiguan/article/details/84547918 https://www.cnblogs.com/ylsforever/p/6600925.html
部分图片来自《RabbitMQ 实战指南》
标签:交换器,入门,队列,简介,RabbitMQ,--,消息,路由 From: https://www.cnblogs.com/wujuntian/p/16644894.html