消息代理(Message Broker): 一种消息验证、传输、路由的架构模式,实现应用程序之间消息传递的解耦
RabbitMQ:实现高级消息队列协议(AMQP)的开源消息代理中间件
AMQP特性:消息方向、消息队列、消息路由(PTP/SB)、可靠性、安全性
1. RabbitMQ基本概念:
- Broker:消息队列服务器的实体,负责接收生产者的消息,然后将消息发送到消息接收者或者其他Broker
- Exchange:消息交换机,消息第一个到达的地方,消息通过它指定的路由规则,分发到不同的消息队列(类似路由器)
- Queue:消息队列:消息通过发送和路由之后达到的地方,到达Queue的消息即进入逻辑上的等待消费状态,每个消息都会发送到一个或多个队列。
- Binding:绑定:将Exchange和Queue按照路由规则绑定起来,是Exchange\Queue的虚拟连接
- Routing Key:路由关键字,Exchange根据关键字进行消息投递
- Virtual host:虚拟主机,对Broker进行虚拟划分,将消费者、生产者和依赖的AMQP相关结构进行隔离,一个Broker可设置多个虚拟主机,对不同的用户进行权限隔离。
- Connection:连接,代表生产者、消费者、Broker之间进行通信的物理网络
- Channel:消息通道,用于连接生产者、消费者的逻辑结构,每个连接可创建多个Channel,每个channel标识一个会话任务,通过channel可隔离同一连接不同的交互内容
- Producer:消息生产者,制造消息并发送消息的程序
- Consumer:消息消费者,接收消息并处理消息的程序
2. 消息投递过程:
- 客户端连接到消息队列服务器,打开channel
- 客户端声明Exchange,设置属性
- 客户端声明Queue,设置属性
- 客户端使用Routing Key,在Exchange和Queue之间建立绑定关系
- 客户端投递消息到Exchange
- Exchange接收消息后根据消息的key和已设置的Binding,进行消息路由,将消息投递到Queue
3.Exchange类型:
- Direct交换机:完全按照Key进行投递
- Topic交换机:对Key进行模式匹配后进行投递: *匹配一个词,#匹配一个或多个词
- Fanout交换机:不需要key,通过广播模式,将消息投递到该交换机绑定的所有队列
- Headers交换机: 根据消息头部决定队列消息分发
消息确认模式:
- Nack message requeue true: 消息确认后是否可重新入队,重新入队消息可重复处理
- Ack message requeue false: 消息确认后不可重新入队,避免消息重复消费
- Reject requeue true: 消息被拒绝,可重新入队
- Reject requeue false: 消息被拒绝,不可重新入队,消息进入死信队列或被丢弃
4. RabbitMQ特性:持久化
- Exchange持久化:声明时指定durable=>1
- Queue持久化:声明时指定durable=>1
- 消息持久化:投递时指定delivery_mode=>2 (1:非持久化)
注意:若Exchange和Queue都持久化,那么Binding也是持久化的,如果Exchange和Queue有一个是非持久化,那么不允许建立绑定
5. rabbit相关命令
5.1 启/停RabbitMQ
启动RabbitMQ服务器:
- 前台启动RabbitMQ服务器: rabbitmq-server start
- 后台启动RabbitMQ服务器: rabbitmq-server -detached (类似shell后台执行命令)
启/停应用:
- rabbitmqctl.bat stop_app
- rabbitmqctl.bat start_app
启用WEB管理工具
- rabbitmq-plugins enable rabbitmq_management
- WEB访问页面:http://localhost:15672 默认用户:guest/guest 注意:RabbitMQ管理工具启用之后,RabbitMQ必须重启,否则无法生效
5.2 用户命令
用户管理基本命令:
- 添加用户:rabbitmqctl add_user <username> <password>
- 删除用户:rabbitmqctl delete_user <username>
- 修改用户密码:rabbitmqctl change_password <username> <newpassword>
- 删除密码:rabbitmqctl clear_password <username>
- 设置用户角色:rabbitmqctl set_user_tags <username> <tag> 执行命令时会清空原有角色,角色可以设置多个或零个;
- 查询所有用户名:rabbitmqctl list_users
- 用户授权(管理员):rabbitmqctl set_user_tags 用户名 administrator
rabbitmq:新增远程访问用户:
- 创建用户:rabbitmqctl add_user 用户名 登陆密码
- 分配角色:rabbitmqctl set_user_tags 用户名 administrator
- 授权: rabbitmqctl set_permissions -p "/" 用户名 "." "." ".*"
5.3 其他常用命令:
- 打印消息队列列表:rabbitmqctl list_queues [-p <vhostpath>] [<queueinfoitem> ...]
- 打印交换机列表:rabbitmqctl list_exchanges [-p <vhostpath>] [<exchangeinfoitem> ...]
- 打印绑定器列表:rabbitmqctl list_bindings [-p <vhostpath>] [<bindinginfoitem> ...]
- 打印连接列表: rabbitmqctl list_connections [<connectioninfoitem> ...]
- 打印消费者列表: rabbitmqctl list_channels [<channelinfoitem> ...]
6. 用户角色
RabbitMQ用户角色: none、management、policymaker、monitoring、administrator
none: 不能访问 management plugin
management
- 用户可以通过AMQP做的任何事外加:
- 列出自己可以通过AMQP登入的virtual hosts
- 查看自己的virtual hosts中的queues, exchanges 和 bindings
- 查看和关闭自己的channels 和 connections
- 查看有关自己的virtual hosts的“全局”的统计信息,包含其他用户在这些virtual hosts中的活动
policymaker
- management可以做的任何事外加:
- 查看、创建和删除自己的virtual hosts所属的policies和parameters
monitoring
- management可以做的任何事外加:
- 列出所有virtual hosts,包括他们不能登录的virtual hosts
- 查看其他用户的connections和channels
- 查看节点级别的数据如clustering和memory使用情况
- 查看真正的关于所有virtual hosts的全局的统计信息
administrator
- policymaker和monitoring可以做的任何事外加:
- 创建和删除virtual hosts
- 查看、创建和删除users
- 查看创建和删除permissions
- 关闭其他用户的connections
指定授权:rabbitmqctl set_permissions -p / 用户名 "." "." ".*"
补充说明: "*"分别表示:配置、写、读权限
7. 集群架构
7.1 主备模式(Warren)
说明:主节点提供消息读写服务,备用节点不负责消息读写处理,若主节点故障备用节点自动切换为主节点提供服务(HaProxy)
场景:并发、数据量不高
HaProxy配置:
listen rabbitmq_cluster
bind 0.0.0.0:5672
mode tcp #配置TCP模式
balance roundrobin #简单的轮询
server bhz76 192.168.11.12:5672 check inter 5000 rise 2 fall 3 #主节点
server bhz77 192.168.11.13:5672 backup check inter 5000 rise 2 fall 3 #备用节点
说明:间隔5s检查健康1次,2次正常表示MQ节点正常,3次故障表示节点故障 backup: 表示备用节点
7.2 远程模式(Shovel: 不常用)
说明:可以将消息进行不同数据中心复制工作,可以实现跨区域的MQ集群互联
模型:近端同步确认、远端异步确认
特点:双活,另外当MQ集群处理到达到瓶颈,新到来的消息可以转发到另外1个区域的MQ集群处理,提高消息处理速度
7.3 镜像模式(实际使用)
说明:MQ节点之间互相实现消息同步,可确保数据100%不丢失,每个集群节点数据完全一致
7.4 多活模式
说明:实现异地数据复制的主流模式,需借助Federation插件实现不同集群队列消息共享,避免单集群故障导致整体系统故障
8. 问题场景
8.1 保证消息不丢失解决方案
生产者丢失数据:消息发送过程中因网络问题发送失败 方案:事务发送消息(同步阻塞:性能慢)、开启confirm模式(异步:推荐)
MQ丢失数据:MQ未持久化或者还未完成持久化,故障导致数据丢失 方案:创建Queue持久化 + 发送消息持久化(deliveryMode=2),该模式下只有消息完成持久化才会回调confirm关联接口
消费者丢失数据:消费者刚消费到,但未处理消费者故障 方案:关闭消费者自动提交ack,消息完全消费完后手动提交
来源:oschina
链接:https://my.oschina.net/yangzhiwei256/blog/4468023