RabbitMQ 消息队列、原理、集群部署

本文深入讲解RabbitMQ消息队列的原理与应用,包括异步处理、流量削峰及架构解耦等场景,探讨RabbitMQ与其他消息队列的对比,详细介绍其特性、工作机制及集群部署步骤。

1. rabbitmq(消息队列)

​ rabbitmq 基于 AMQP协议: 属于高级消息队列协议,是应用层开放的协议,为面向消息中间件涉及,它可以使客户端与对应的消息中间件进行交互,消息中间件从发布者哪里接收到消息,然后转发给消费者(处理消息的应用)

概念

RabbitMQ是一个遵循AMQP协议的消息中间件,它从生产者接受消息并传递给消费者,在这和过程中,根据路由规则进行路由、缓存和持久化。

消息队列应用的场景

1) 异步处理

​ 在注册服务的时候,如果同步串行化的方式处理,让存储数据、邮件通知等挨着完成,延迟较大,采用消息队列,可以将邮件服务分离开来,将邮件任务之间放入消息队列中,之后返回,减少了延迟,提高了用户体验;

2) 流量消峰

​ 典型的使用场景就是秒杀业务用于流量削峰场景

​ 如淘宝购物节,先进先出原则。 秒杀活动中,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。 服务器在接收到用户请求后,首先写入消息队列。这时如果消息队列中消息数量超过最大数量,则直接拒绝用户请求或返回跳转到错误页面。秒杀业务根据秒杀规则读取消息队列中的请求信息,进行后续处理;

3) 架构解耦

​ 解耦是 消息列队要解决的最本质的问题

​ 电商里面,在订单与库存系统的中间添加一个消息队列服务器,在用户下单后,订单系统将数据先进行持久化处理,然后将消息写入消息队列,直接返回订单创建成功,然后库存系统使用拉/推的方式,获取订单信息再进行库存操作;


2. 消息队列的种类

redis 消息能够先进先出

memcacheq 拥有多条队列,并发性能比价好,完美的兼容 memcache

MSMQ 只有发送和接收的功能,消息的最大载体,只有4M

zeromq 号称最快的消息队列,高 吞吐、低延迟、 在金融方面用的比较多

kafka 用于日志手机, 支持快速的持久化,高吞吐

activemq java 的中坚力量, java 语言支持的比较好

rabbitmq 属于开源,最早的、最稳定的重量级 消息队列, 消息封装比较大,扩展性能比较差, 不能持久化

3. RabbitMQ 特点

  • RabbitMQ 是一个由 Erlang 语言开发的AMQP 的开源实现

1) 可靠性

​ RabbitMQ 最初起源于金融系统,用于在分布式系统中存储转发系消息,在易用性、扩展性、高可用性等方面表现不俗。

2) 灵活的路由

​ 在消息进入队列之前通过 Exchange 来路由消息的,对于典型路由功能,RabbitMQ 已经提供了一些内置的Exchange来实现,针对更复杂的路由功能,可以将多个Exchange 绑定在一起

3) 消息集群

​ 多个RabbitMQ 服务器可以组成一个集群,形成一个逻辑 Broker

4) 支持多种协议

​ STOMP、MQTT

5) 多语言客户端

Java、NET、Ruby

6) 管理界面

​ RabbitMQ 提供一个易用的用户界面,使用户可以监控和管理消息


4. RabbitMQ 工作机制

  • 了解消息队列之前要了解 三个概念: 生产者、消费者、代理

  • 生产者: 消息的创建者,负责创建和推送消息到消息服务器

  • 消费者: 消息的接收方,用于处理数据和确认消息

  • 代理: 就是RabbitMQ 本身,用于扮演“快递”的角色,本身不生产消息,只是扮演一个 快递的角色

1) RabbitMQ 名词

  • rabbitmq server(消息队列架构)
    • 用于接收生产者的消息,并将消息分配给消费者
  • producer(生产者)
    • 生产消息,消息分为两个部分,标签,数据,标签用于匹配规则
  • Consumer(消费者)
    • 用来消费 消息队列分配的消息
  • Ack回应
    • 用于判断消费者是否被消费,如果检测到被消费,则这个消息会被删除,如果检测到未被消费,则这个消息会被回转,等待再次消费
  • Exchange(交换机)
    • 用于接收、分配消息
  • Connection
    • 生产者、消费者、消息队列进行连接
  • Channel(信道)
    • 虚拟通道,消息推送实用的通道
  • Queue(队列)
    • 用于存储生产的消息
  • RoutingKey(路由键)

    • 用于把生产者的数据分配到交换机上
  • BindingKey(绑定建)

    • 用于把交换机的消息绑定至队列上

2) 消息队列发送原理

在这里插入图片描述

在这里插入图片描述

  • 首先你必须连接到 RabbitMQ 才能发布和消费消息,

  • 你的应用程序和Rabbit server 之间会创建一个 TCP 连接,一旦TCP 打开,并通过了认证,认证就是你试图连接的Rabbit 之前发送的Rabbit 服务器连接信息和用户名和密码,有点想程序连接数据库。

  • 当Client 使用 APP 产生了消息,会先与Rabbit Server 进行连接,连接之后会建立一个消息通道(Channel),通过消息通道将producer(生产者)生产的数据发送至 Exchange(交换器) 上,由Exchange 接收并根据其匹配规则来转发至对应的Queue(队列上) 然后通过队列在将消息传输给Consumer(消费者)进行处理,然后返回ACK回应消息

3) 消息持久化

  • Rabbit 队列和交换机有一个小秘密,就是默认情况下重启服务器会导致消息丢失,为了保证消息在重启时不丢失,要用到持久化

    • 持久化要满足一下条件
      • 投递消息的时候durable设置为true,消息持久化,代码:channel.queueDeclare(x, true, false, false, null),参数2设置为true持久化;
      • 设置投递模式deliveryMode设置为2(持久),代码:channel.basicPublish(x, x, MessageProperties.PERSISTENT_TEXT_PLAIN,x),参数3设置为存储纯文本到磁盘;
      • 消息已经到达持久化交换器上;
      • 消息已经到达持久化的队列;
  • 持久化工作原理
    • Rabbit 会将你的持久化消息写入磁盘上的持久化日志文件中,等消息被消费之后,Rabbit 会把这条消息标识为等待垃圾回收
  • 持久化缺点
    • 性能降低,因为要写入硬盘内,从而降低了Rabbit 的性能

5. RabbitMQ 命令行的基本操作

  • 服务端后台方式启动
    • rabbitmq-server start &
      
  • 查看所有消息队列
    • rabbitmqctl list_queues
      
  • 查看所有虚拟主机
    • rabbitmqctl list_vhosts
      
  • 启动应用
    • rabbitmqctl start_app
      
  • 停止应用
    • rabbitmqctl stop_app
      
  • 查看节点状态
    • rabbitmqctl status
      
  • 添加用户
    • rabbitmqctl  add_user username password
      
  • 列出所有用户
    • rabbitmqctl list_users
      
  • 删除用户
    • rabbitmqctl  delete_user username
      
  • 清除用户权限
    • rabbitmqctl  clear_permissions  -p  vhostpath  username
      
  • 列出用户权限
    • rabbitmqctl  list_user_permissions username
      
  • 修改密码
    • rabbitmqctl  change_password  username  newpassword
      
  • 创建虚拟主机
    • rabbitmqctl add_vhost vhostpath
      
  • 删除虚拟主机
    • rabbitmqctl delete_vhost vhost vhostpath
      
  • 组成集群命令
    •  rabbitmqctl join_cluster <clusternode> [--ram]
      
  • 查看集群状态
    • rabbitmqctl cluster_status
      
  • 移除节点
    • rabbitmqctl   forget_cluster_node  [--offline] 
      

6. RabbitMQ 集群

  • 实验环境
HostIPHost-name
RabbitMQ-11.1.1.101one
RabbitMQ-21.1.1.102two
RabbitMQ-31.1.1.103three

1) 安装RabbitMQ

  • 修改主机名
[root@localhost ~]# hostnamectl set-hostname one
  • 安装 Erlang语言环境
    • RabbitMQ 需要 Erlang 支持
[root@localhost ~]# rpm -ivh erlang-18.1-1.el7.centos.x86_64.rpm 
准备中...                          ################################# [100%]
正在升级/安装...
   1:erlang-18.1-1.el7.centos         ################################# [100%]
  • 安装socat,为了RabbitMQ-server依赖包
[root@localhost ~]# yum -y install socat
  • 安装RabbitMQ Server
[root@localhost ~]# rpm -ivh rabbitmq-server-3.6.15-1.el7.noarch.rpm 
警告:rabbitmq-server-3.6.15-1.el7.noarch.rpm: 头V4 RSA/SHA1 Signature, 密钥 ID 6026dfca: NOKEY
准备中...                          ################################# [100%]
正在升级/安装...
   1:rabbitmq-server-3.6.15-1.el7     ################################# [100%]
  • Rabbitmq 2
[root@localhost ~]# hostnamectl set-hostname two
[root@localhost ~]# rpm -ivh erlang-18.1-1.el7.centos.x86_64.rpm 
准备中...                          ################################# [100%]
正在升级/安装...
   1:erlang-18.1-1.el7.centos         ################################# [100%]
[root@localhost ~]# yum -y install socat
[root@localhost ~]# rpm -ivh rabbitmq-server-3.6.15-1.el7.noarch.rpm 
警告:rabbitmq-server-3.6.15-1.el7.noarch.rpm: 头V4 RSA/SHA1 Signature, 密钥 ID 6026dfca: NOKEY
准备中...                          ################################# [100%]
正在升级/安装...
   1:rabbitmq-server-3.6.15-1.el7     ################################# [100%]
  • Rabbitmq 3
[root@localhost ~]# hostnamectl set-hostname three
[root@localhost ~]# rpm -ivh erlang-18.1-1.el7.centos.x86_64.rpm 
准备中...                          ################################# [100%]
正在升级/安装...
   1:erlang-18.1-1.el7.centos         ################################# [100%]
[root@localhost ~]# yum -y install socat
[root@localhost ~]# rpm -ivh rabbitmq-server-3.6.15-1.el7.noarch.rpm 
警告:rabbitmq-server-3.6.15-1.el7.noarch.rpm: 头V4 RSA/SHA1 Signature, 密钥 ID 6026dfca: NOKEY
准备中...                          ################################# [100%]
正在升级/安装...
   1:rabbitmq-server-3.6.15-1.el7     ################################# [100%]

2) 编写 Host 解析文件

  • 用于识别主机
[root@one ~]# vim /etc/hosts
1.1.1.101 one
1.1.1.102 two
1.1.1.103 three
  • 都需要做
[root@one ~]# scp /etc/hosts root@1.1.1.102:/etc/
[root@one ~]# scp /etc/hosts root@1.1.1.103:/etc/

3) 启动 RabbitMQ

[root@one ~]# systemctl restart rabbitmq-server
  • 查看当前状态
[root@one ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@one
[{nodes,[{disc,[rabbit@one]},{ram,[rabbit@two]}]},
 {running_nodes,[rabbit@two,rabbit@one]},
 {cluster_name,<<"rabbit@two">>},
 {partitions,[]},
 {alarms,[{rabbit@two,[]},{rabbit@one,[]}]}]

4) 创建集群

  • rabbitmq的 群集的 是由三个 一致的 cookie值组成的,所以需要将另外两台的 cookie值 改为 one 的cookie

  • 查看Rabbitmq -1 的cookie值

    • 如果三台 rabbitmq 的cookie 值一致的话,表示三台为一个群集
[root@one ~]# cat /var/lib/rabbitmq/.erlang.cookie 
EWKBMDAULAKJOCROJAEZ
  • 将 two 服务器加入 到 one 的群集中
    • 启动 rabbitmq 服务, 并将 one 主机 的 cookie 设置 two主机 cookie值
[root@one ~]# systemctl start rabbitmq-server
[root@two ~]# echo "EWKBMDAULAKJOCROJAEZ" > /var/lib/rabbitmq/.erlang.cookie 
# 然后重新启动主机,使 cookie值生效

# 开机之后,重新启动 rabbitmq 服务 
[root@two ~]# systemctl restart rabbitmq-server

# 停止群集服务,
[root@two ~]# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@two

# 将 two主机 加入到 one 群集中, one 为主机名
[root@two ~]# rabbitmqctl join_cluster rabbit@one --ram
Clustering node rabbit@two with rabbit@one

# 将群集功能启动
[root@two ~]# rabbitmqctl start_app
Starting node rabbit@two              # 提示当前 属于 one

# 查看当前状态
[root@two ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@two 
[{nodes,[{disc,[rabbit@one]},{ram,[rabbit@two]}]},
 {running_nodes,[rabbit@one,rabbit@two]},
 {cluster_name,<<"rabbit@two">>},
 {partitions,[]},
 {alarms,[{rabbit@one,[]},{rabbit@two,[]}]}]
  • 将three服务器加入 到 one 的群集中
    • 启动 rabbitmq 服务, 并将 one 主机 的 cookie 设置 two主机 cookie值
[root@one ~]# systemctl start rabbitmq-server

[root@two ~]# echo "EWKBMDAULAKJOCROJAEZ" > /var/lib/rabbitmq/.erlang.cookie 
# 重新启动主机

[root@three ~]# systemctl restart rabbitmq-server

[root@three ~]# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@three

[root@three ~]# rabbitmqctl join_cluster rabbit@one --ram
Clustering node rabbit@three with rabbit@one

[root@three ~]# rabbitmqctl start_app
Starting node rabbit@three

[root@three ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@three
[{nodes,[{disc,[rabbit@one]},{ram,[rabbit@two,rabbit@three]}]},
 {running_nodes,[rabbit@two,rabbit@one,rabbit@three]},
 {cluster_name,<<"rabbit@two">>},
 {partitions,[]},
 {alarms,[{rabbit@two,[]},{rabbit@one,[]},{rabbit@three,[]}]}]

5) 添加插件

  • 添加管理插件,必须添加,用于提供图形化界面

    • 三台都需要添加
  • 启用插件

rabbitmq-plugins enable rabbitmq_management	
  • 删除默认用户
[root@one ~]# rabbitmqctl delete_user guest
Deleting user "guest"

  • 创建用户 one,并设置密码为 123.com
[root@one ~]# rabbitmqctl add_user one 123.com
Creating user "one"
  • 赋予 one 用户,管理员标签
[root@one ~]# rabbitmqctl set_user_tags one administrator
Setting tags for user "one" to [administrator]

6) 使用Rabbit MQ

  • 浏览器 访问:http://rabbitmq-ip:port

  • 添加一个虚拟主机

  • 通过下午我们可以看到所创建的虚拟主机
    • 每一个虚拟主机等于一个消息队列

在这里插入图片描述

  • 查看虚拟主机详细信息
    • 以下表示接收所有的数据

  • 添加策略
    在这里插入图片描述

  • 匹配规则

    • name 策略名称
    • pattern 匹配规则
    • apply to 直接绑定

在这里插入图片描述

  • 将策略与 Queue(消息队列)绑定

在这里插入图片描述

在这里插入图片描述

  • 在服务器中查看消息队列
[root@one ~]# ls /var/lib/rabbitmq/mnesia/rabbit\@one/queues/
EX4CG07HWR5KMBKGP20UYQEV7
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值