什么是消息中间件
- 消息 是指在应用之间传递的数据。可以是文本,Json等,也可以很复杂,比如内嵌对象。
- 消息队列中间件 Message Queue Middleware 简称MQ,是指利用高效可靠的传输机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。 目前主流的消息队列中间件有 RabbitMQ、Kafka、ActiveMQ、RoekctMQ等。
消息中间件的作用
- 解藕
- 冗余
- 扩展性
- 削峰
- 可恢复性
- 顺序保证
- 缓冲
- 异步通信
RabbitMQ的特点
RabbitMQ最初起源于金融系统,用于在分布式系统中存储转发消息。
- 可靠性: RabbitMQ使用一些机制来保证可靠性,如持久化、传输确认以及发布确认等。
- 灵活的路由:在进入消息队列前,通过交换器来路由消息。
- 扩展性:多个RabbitMQ节点可以组成一个集群,也可以根据实际业务动态扩展集群中的节点。
- 高可用性: 队列可以在集群中设置镜像,使得部分节点在出现问题的情况下队列仍然可用
- 多种协议:除了原生支持AMQP协议外,还支持STOMP、MQTT等协议。
- 多语言客户端: 几乎支持所有常见语言,比如Java、Python、Ruby、PHP等。
- 管理界面:RabbitMQ提供了一个易用的用户界面,使得用户可以监控和管理。
- 插件机制: 提供了许多插件,以实现多方面的扩展。
RabbitMQ的安装
RabbitMQ是以Erlang语言编写的,因此安装rabbitMQ之前需要安装Erlang。 要注意RabbitMQ的版本和Erlang之间的版本对应关系。
RabbitMQ的基本概念
- Producer: 生产者
- Consumer:
- Broker:
- Queue:
- Exchange:
- RouterKey:
- BindingKey:
RabbitMQ的运转流程
- 生产者运转流程
- 消费者运转流程
RabbitMQ基本方法
包含以下基本操作 代码(略)
- 建立RabbitMQ连接
- 使用交换器和队列 exchangeDeclare queueDeclare queueBind exchangeBind
- 发送消息
- 消费消息 推模式 拉模式
- 消费端的确认和拒绝
- 关闭连接
RabbitMQ进阶
- 消息何去何从 1、chanel.basicPublish 方法中的两个参数: mandatory: 值为true时,交换器无法根据自身的类型和路由键找到一个符合条件的队列时,那么RabbitMQ会令消息返回给生产者;值为false时,出现上述情景时,消息会直接丢弃。 immediate: 值为true时,如果交换机在讲消息路由到队列时,发现并不存在任何消费者,那么这条消息不会进入队列。(RabbitMQ 3.0开始去掉了对该参数的支持) 2、备份交换器 生产者在发消息的时候,如果不设置mandatory参数,那么消息在未被路由的情况下将会丢失;如果设置了mandatory参数,那么需要添加RetureListener的编程逻辑,代码变得复杂。如果不想复杂化生产者的编程逻辑,又不想消息丢失,可以使用备份交换器,未被路由的消息可以存储在RabbitMQ中,再在需要的时候去处理这些消息。
- 过期时间TTL 有两种方法可以设置消息的TTL。1,通过队列属性设置,队列中所有消息都有相同的过期时间。第二种方法是对消息本身进行单独设置,每条消息的TTL可以不同。当两者都设置的时候,以较TTL较小值为准。
- 死信队列 当消息在一个队列中编程死信之后,它能被重新发送到另一个交换器中,这个交换器就是死信交换器,与死信交换器绑定的队列就是死信队列。 消息变死信一般由于以下几种情况: 消息被拒绝、消息过期、队列达到最大长度
- 延迟队列 延迟消息指的是当消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。
- 优先级队列 优先级高的队列中,消息会被优先消费。
- RPC实现 在RabbitMQ中进行RPC是很简单的,客户端发送请求消息,服务端回复相应消息。
- 持久化 持久化可以提高RabbitMQ的可靠性,RabbitMQ的持久化可以分为3个部分:交换器的持久化、队列的持久化、消息的持久化。
- 生产者确认 当生产者的消息发出去以后,消息到底有没有正确到底服务器呢?可以通过两种方式来实现: 通过事务机制/通过发送方确认机制
- 消费端要点介绍 消息分发:消息分发最主要的,就是保证所有消费都能被合理分配到任务量。 消息顺序性:指消费者消费到的消息和发布者发布消息的顺序是一致的。 弃用QueueConsumer:
- 消息传输保障 一般消息中间件的消息传输保障可以分为3个等级 最多一次:(RabbitMQ支持该等级)消息可能会丢失,但是绝不重复传输。 最少一次:(RabbitMQ支持该等级)消息绝不会丢失,但可能重复传输。 该等级需要考虑以下几个方面的内容: 1,消息生产者需要开启事务机制或者publisher confirm机制,以确保消息可以可靠的传输到RabbitMQ中。 2,消息生产者需要配合mandatory参数或者备份交换器来保证消息能够从交换器路由到队列中,进而能保存下来,而不至于丢失。 3,消息和队列都需要进行持久化处理,以确保RabbitMQ服务器在遇到异常情况下不会造成消息丢失。 4,消费者在消费消息的同时,需要讲autoAck设置为false,然后通过手动确认的方式去确认已经正确消费的消息,以避免在消费端引起不必要的丢失。 恰好一次:(RabbitMQ不支持该等级)消息肯定要被传输一次且仅传输一次。
RabbitMQ管理
- 多租户与权限 每一个RabbitMQ服务器都能创建虚拟的消息服务器,我们称之为Vhost。每个vhost本质上是一个小型的独立的RabbitMQ服务器,拥有自己独立的队列、交换器及绑定关系。 vhost是AMQP概念的基础,客户端建立连接的时候必须要创建一个vhost,RabbitMQ默认创建的vhost是“/”。
- 用户管理 用户的角色类型分为5种 none 无任何角色,新创建的用户角色默认为none。 management:可以访问web管理界面。 pllicymaker:包含management的所有权限,并且可以管理策略和参数。 monitoring:包含management的所有权限,并且可以看到所有连接、信道及节点相关信息。 administrator:包含monitoring的所有权限,并且可以管理用户、虚拟主机、权限、策略、参数等。代表了最高权限。
- web端管理 可以通过management插件来管理
- 应用与集群管理 包括一些与集群相关的操作管理命令,包括关闭、重置和开启服务。还有建立集群的一些相关操作
- 服务端状态 包括一些列查询状态的操作语句
- HTTP API 接口管理 RabbitMQ Management插件不仅提供了web管理界面,还提供了HTTP API接口来方便调用。
RabbitMQ配置
提供了三种方式来定制化服务 1,环境变量 2,配置文件 3,运行时的参数和策略
RabbitMQ 集群搭建
RabbitMQ集群中所有的节点都会备份所有的元数据信息,包括队列元数据、交换器、绑定关系元数据、vhost元数据,但是不会备份消息。
- 多机多节点配置 1,首先配置各个节点的hosts文件,让各个节点都意识到对方的存在。 2,编辑RabbitMQ的cookie文件,以确保各个节点的cookie文件使用的是同一个值。 3,建立集群。
- 剔除单个节点 首先在该节点上关闭RabbitMQ服务,然后在其他节点上,忘记该节点。
- 集群节点的升级 如果集群节点由单独的一个节点组成,那么升级版本只需要关闭原来的服务,然后解压新的版本再运行即可。如果是多个节点的集群具体步骤如下: 1,关闭所有节点的服务 2,保存各个节点的Mnesia数据 3,解压新版本的RabbitMQ到指定的目录 4,指定新版本的Mnesia路径为步骤2中保存的Mnesia数据路径。 5,启动新版本的服务,注意先重启原版本中最后关闭的那个节点。
- 单机多节点配置 首先确保在机器上安装了Erlang和RabbitMQ服务,其次,为每个RabbitMQ服务节点设置不同的端口号和节点名称来启动相应的服务。 如果开启了RabbitMQ Management插件,就需要为每个服务节点配置一个对应的插件端口号。
RabbitMQ服务日志
RabbitMQ的日志默认放在¥RABBITMQ_HOME/var/log/rabbitmq文件夹内。在这个文件夹内RabbitMQ会创建两个日志文件:RABBITMQ_NODENAME-sas1.log和RABBITMQ_NODENAME.log。 服务日志包含5个等级,none/error/warning/info/debug,每一个级别均包含上一个级别的日志。
RabbitMQ单节点故障恢复
单节点故障包括:机器硬件故障、机器掉电、网络异常、服务异常等。 通常情况下,遇到故障后,应该先在其他节点中忘记故障节点,然后重启故障节点重新加入集群。
集群迁移
集群迁移包括三个步骤 元数据重建、数据迁移 以及 与客户端连接的切换。
跨越集群的界限
RabbitMQ可以通过3种不同的方式实现分布式部署:集群、Federation和Shovel。这三种方式不是互斥的,可以组合使用。
- Federation 插件能够在不同的管理域中的Broker节点之间进行消息传递而无需建立集群。
- Shovel 能够、持续的从一个Broker中的队列拉数据并转发至另一个Broker中的交换器。