一、MQ介绍
1.1、什么事MQ
MQ
(Message Quene) : 翻译为 消息队列
,通过典型的 生产者
和消费者
模型,生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息。因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没有业务逻辑的侵入,轻松的实现系统间解耦。别名为 消息中间件
通过利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。
1.2、MQ有哪些
当今市面上有很多主流的消息中间件,如老牌的ActiveMQ
、RabbitMQ
,炙手可热的Kafka
,阿里巴巴自主开发RocketMQ
等。
1.3、不同MQ特点
# 1.ActiveMQ ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。它是一个完全支持JMS规范的的消息中间件。丰富的API,多种集群架构模式让ActiveMQ在业界成为老牌的消息中间件,在中小型企业颇受欢迎! # 2.Kafka Kafka是LinkedIn开源的分布式发布-订阅消息系统,目前归属于Apache顶级项目。Kafka主要特点是基于Pull的模式来处理消息消费, 追求高吞吐量,一开始的目的就是用于日志收集和传输。0.8版本开始支持复制,不支持事务,对消息的重复、丢失、错误没有严格要求, 适合产生大量数据的互联网服务的数据收集业务。 # 3.RocketMQ RocketMQ是阿里开源的消息中间件,它是纯Java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。RocketMQ思路起 源于Kafka,但并不是Kafka的一个Copy,它对消息的可靠传输及事务性做了优化,目前在阿里集团被广泛应用于交易、充值、流计算、消 息推送、日志流式处理、binglog分发等场景。 # 4.RabbitMQ RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和 发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在 其次。
RabbitMQ比Kafka可靠,Kafka更适合IO高吞吐的处理,一般应用在大数据日志处理或对实时性(少量延迟),可靠性(少量丢数据)要求稍低的场景使用,比如ELK日志收集。
1.4、MQ应用场景
1.4.1、异步处理
场景说明:用户注册后,需要发注册邮件和注册短信,传统的做法有两种 1.串行的方式 2.并行的方式
1)串行方式
将注册信息写入数据库后,发送注册邮件,再发送注册短信,以上三个任务全部完成后才返回给客户端。 这有一个问题是,邮件,短信并不是必须的,它只是一个通知,而这种做法让客户端等待没有必要等待的东西.
2)并行方式
将注册信息写入数据库后,发送邮件的同时,发送短信,以上三个任务完成后,返回给客户端,并行的方式能提高处理的时间。
3)消息队列
假设三个业务节点分别使用50ms,串行方式使用时间150ms,并行使用时间100ms。虽然并行已经提高的处理时间,但是,前面说过,邮件和短信对我正常的使用网站没有任何影响,客户端没有必要等着其发送完成才显示注册成功,应该是写入数据库后就返回.
消息队列
: 引入消息队列后,把发送邮件,短信不是必须的业务逻辑异步处理
由此可以看出,引入消息队列后,用户的响应时间就等于写入数据库的时间+写入消息队列的时间(可以忽略不计),引入消息队列后处理后,响应时间是串行的3倍,是并行的2倍。
1.4.2、应用解耦
场景:双11是购物狂节,用户下单后,订单系统需要通知库存系统,传统的做法就是订单系统调用库存系统的接口.
这种做法有一个缺点:当库存系统出现故障时,订单就会失败。 订单系统和库存系统高耦合. 引入消息队列:
1.4.3、流量削峰
场景: 秒杀活动,一般会因为流量过大,导致应用挂掉,为了解决这个问题,一般在应用前端加入消息队列。
作用:
1.用户的请求,服务器收到之后,首先写入消息队列,加入消息队列长度超过最大值,则直接抛弃用户请求或跳转到错误页面.
2.秒杀业务根据消息队列中的请求信息,再做后续处理.
二、RabbitMQ 的引言
2.1、RabbitMQ
基于AMQP
协议,erlang语言开发,是部署最广泛的开源消息中间件,是最受欢迎的开源消息中间件之一。
官方教程
: https://www.rabbitmq.com/#getstarted
2.2、AMQP协议
AMQP(advanced message queuing protocol)`在2003年时被提出,最早用于解决金融领不同平台之间的消息传递交互问题。顾名思义,AMQP是一种协议,更准确的说是一种binary wire-level protocol(链接协议)。这是其和JMS的本质差别,AMQP不从API层进行限定,而是直接定义网络交换的数据格式。这使得实现了AMQP的provider天然性就是跨平台的。以下是AMQP协议模型:
2.3、RabbitMQ安装
rabbitmq下载地址:
https://www.rabbitmq.com/download.html
erlang下载地址:
https://dl.bintray.com/rabbitmq-erlang/rpm/erlang/22/el/7/x86_64/erlang-22.2.8-1.el7.x86_64.rpm
rabbitmq和erlang版本需要对应:
https://www.rabbitmq.com/which-erlang.html
此处我下载的安装包版本如下:
1)将rabbitmq安装包上传到linux系统中
[root@service008 ~]# ll total 34388 -rw-r--r-- 1 root root 19782364 Aug 18 15:43 erlang-22.3-1.el7.x86_64.rpm -rw-r--r-- 1 root root 15429219 Aug 18 15:46 rabbitmq-server-3.8.6-1.el7.noarch.rpm
2)安装Erlang依赖包
[root@service008 ~]# rpm -ivh erlang-22.3-1.el7.x86_64.rpm warning: erlang-22.3-1.el7.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID 6026dfca: NOKEY Preparing... ################################# [100%] Updating / installing... 1:erlang-22.3-1.el7 ################################# [100%]
3)安装RabbitMQ安装包,需要先安装socat依赖
[root@service008 ~]# rpm -ivh rabbitmq-server-3.8.6-1.el7.noarch.rpm warning: rabbitmq-server-3.8.6-1.el7.noarch.rpm: Header V4 RSA/SHA256 Signature, key ID 6026dfca: NOKEY error: Failed dependencies: socat is needed by rabbitmq-server-3.8.6-1.el7.noarch [root@service008 ~]# yum install socat -y [root@service008 ~]# rpm -ivh rabbitmq-server-3.8.6-1.el7.noarch.rpm warning: rabbitmq-server-3.8.6-1.el7.noarch.rpm: Header V4 RSA/SHA256 Signature, key ID 6026dfca: NOKEY Preparing... ################################# [100%] Updating / installing... 1:rabbitmq-server-3.8.6-1.el7 ################################# [100%]
4)创建配置文件
新版本默认没有配置,需要自己创建,配置模板可以在github上下载
https://github.com/rabbitmq/rabbitmq-server/blob/v3.8.6/docs/rabbitmq.conf.example
原先的版本,如3.7.18,在服务器上存在配置模板的:/usr/share/doc/rabbitmq-server-3.7.18/rabbitmq.config.example
在/etc/rabbitmq下创建rabbitmq.conf,并配置
5)启动rabbitmq中的插件管理
[root@service008 rabbitmq]# rabbitmq-plugins enable rabbitmq_management Enabling plugins on node rabbit@service008: rabbitmq_management The following plugins have been configured: rabbitmq_management rabbitmq_management_agent rabbitmq_web_dispatch Applying plugin configuration to rabbit@service008... The following plugins have been enabled: rabbitmq_management rabbitmq_management_agent rabbitmq_web_dispatch set 3 plugins. Offline change; changes will take effect at broker restart.
6)启动RabbitMQ的服务
[root@service008 rabbitmq]# systemctl start rabbitmq-server [root@service008 rabbitmq]# systemctl enable rabbitmq-server Created symlink from /etc/systemd/system/multi-user.target.wants/rabbitmq-server.service to /usr/lib/systemd/system/rabbitmq-server.service. [root@service008 rabbitmq]# netstat -lntp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:25672 0.0.0.0:* LISTEN 13940/beam.smp #集群管理端口 tcp 0 0 0.0.0.0:4369 0.0.0.0:* LISTEN 13525/epmd tcp 0 0 0.0.0.0:81 0.0.0.0:* LISTEN 8217/nginx: master tcp 0 0 0.0.0.0:15672 0.0.0.0:* LISTEN 13940/beam.smp #web管理端口 tcp 0 0 0.0.0.0:2812 0.0.0.0:* LISTEN 2318/sshd tcp6 0 0 :::5672 :::* LISTEN 13940/beam.smp #服务端口 tcp6 0 0 :::4369 :::* LISTEN 13525/epmd
7)访问web管理界面
修改默认用户密码:https://blog.csdn.net/crystalqy/article/details/93759883
2.4、rabbitmq管理命令
#服务启停相关 systemctl start|restart|stop|status rabbitmq-server # 启动应用 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 set_permissions -p vhostpath username ".*" ".*" ".*" # 创建虚拟主机 rabbitmqctl add_vhost vhostpath # 列出所有虚拟主机 rabbitmqctl list_vhosts # 列出虚拟主机上所有权限 rabbitmqctl list_permissions -p vhostpath # 删除虚拟主机 rabbitmqctl delete_vhost vhostpath # 查看所有队列 rabbitmqctl list_queues # 清除队列中信息 rabbitmqctl -p vhostpath purge_queue blue # 移除所有数据,要在stop后使用 rabbitmqctl reset # 组成集群 --ram是内存级别存储 rabbitmqctl join_cluster <clusternode> [--ram] # 查看集群状态 rabbitmqctl cluster_status # 修改集群节点存储形式 rabbitmqctl change_cluster_node_type disc | ram # 忘记节点(比如启动不起来的节点,失败转移) rabbitmqctl forget_cluster_node [--offline] # 管理命令行 用来在不使用web管理界面情况下命令操作RabbitMQ rabbitmqctl help 可以查看更多命令 # 插件管理命令行 rabbitmq-plugins enable|list|disable
查看状态:
[root@service008 rabbitmq]# rabbitmqctl status Status of node rabbit@service008 ... Runtime OS PID: 13940 OS: Linux Uptime (seconds): 2978 RabbitMQ version: 3.8.6 Node name: rabbit@service008 Erlang configuration: Erlang/OTP 22 [erts-10.7] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:64] [hipe] Erlang processes: 444 used, 1048576 limit Scheduler run queue: 1 Cluster heartbeat timeout (net_ticktime): 60 Plugins Enabled plugin file: /etc/rabbitmq/enabled_plugins Enabled plugins: * rabbitmq_management * amqp_client * rabbitmq_web_dispatch * cowboy * cowlib * rabbitmq_management_agent Data directory Node data directory: /var/lib/rabbitmq/mnesia/rabbit@service008 Raft data directory: /var/lib/rabbitmq/mnesia/rabbit@service008/quorum/rabbit@service008 Config files * /etc/rabbitmq/rabbitmq.conf Log file(s) * /var/log/rabbitmq/rabbit@service008.log * /var/log/rabbitmq/rabbit@service008_upgrade.log Alarms (none) Memory Total memory used: 0.0953 gb Calculation strategy: rss Memory high watermark setting: 0.4 of available memory, computed to: 13.4269 gb other_proc: 0.0286 gb (26.11 %) code: 0.0268 gb (24.5 %) allocated_unused: 0.0249 gb (22.79 %) other_system: 0.0143 gb (13.07 %) plugins: 0.0093 gb (8.46 %) other_ets: 0.0032 gb (2.96 %) atom: 0.0016 gb (1.43 %) mgmt_db: 0.0002 gb (0.22 %) metrics: 0.0002 gb (0.19 %) binary: 0.0001 gb (0.13 %) mnesia: 0.0001 gb (0.07 %) quorum_ets: 0.0 gb (0.04 %) msg_index: 0.0 gb (0.03 %) connection_other: 0.0 gb (0.0 %) connection_channels: 0.0 gb (0.0 %) connection_readers: 0.0 gb (0.0 %) connection_writers: 0.0 gb (0.0 %) queue_procs: 0.0 gb (0.0 %) queue_slave_procs: 0.0 gb (0.0 %) quorum_queue_procs: 0.0 gb (0.0 %) reserved_unallocated: 0.0 gb (0.0 %) File Descriptors Total: 2, limit: 32671 Sockets: 0, limit: 29401 Free Disk Space Low free disk space watermark: 0.05 gb Free disk space: 144.1589 gb Totals Connection count: 0 Queue count: 0 Virtual host count: 1 Listeners Interface: [::], port: 15672, protocol: http, purpose: HTTP API Interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication Interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
2.5、web管理
2.5.1、概览
2.5.2、Admin用户和虚拟主机管理
1)添加用户
上面的Tags选项,其实是指定用户的角色,可选的有以下几个:
- 超级管理员(administrator):可登陆管理控制台,可查看所有的信息,并且可以对用户,策略(policy)进行操作。
- 监控者(monitoring):可登陆管理控制台,同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)
- 策略制定者(policymaker):可登陆管理控制台, 同时可以对policy进行管理。但无法查看节点的相关信息(上图红框标识的部分)。
- 普通管理者(management):仅可登陆管理控制台,无法看到节点信息,也无法对策略进行管理。
- 其他:无法登陆管理控制台,通常就是普通的生产者和消费者。
添加好之后如下,没有虚拟主机的访问权限:
2)创建虚拟主机
为了让各个用户可以互不干扰的工作,RabbitMQ添加了虚拟主机(Virtual Hosts)的概念。其实就是一个独立的访问路径,不同用户使用不同路径,各自有自己的队列、交换机,互相不会影响。
3)绑定虚拟主机和用户
创建好虚拟主机,我们还要给用户添加访问权限,点击添加好的虚拟主机,进入虚拟机设置界面: