1、中间件
中间件(Middleware),又译中间件、中介层,是一类提供系统软件和应用软件之间连接、便于软件各部件之间的沟通的软件,应用软件可以借助中间件在不同的技术架构之间共享信息与资源。中间件位于客户机服务器的操作系统之上,管理着计算资源和网络通信。
中间件大致分为如下几类:
- 分布式消息中间件:ActiveMQ、RabbitMQ、Kafka、RocketMQ
- 负载均衡中间件:Nginx、LVS负载均衡软件、KeepAlive、CDN
- 缓存中间件:Memcache、Redis
- 数据库中间件:mycat、shardingjdbc
2、消息中间件
消息中间件(Message Queue),是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信,比如下面的分布式系统架构图。
加入消息中间件以后的系统具有如下优势:
(1)应用解耦,提升容错性和可维护性
比如有一个A系统,产生了数据m,B、C、D系统都需要这份数据,A系统可以分别把这份数据发送过去。现在新增了一个系统N,也需要这份数据,这时需要修改A系统的代码把这个数据也发过去,如果过几天N系统被干掉了,那又得修改A系统的代码,取消数据发送到N系统
这个时候如果在A系统和它的下游系统之间加一层,A系统把数据发送到这一层,其他层到中间层取,就可以很完美的解决这个问题。
如果A系统进行了更新升级,也不会影响下游系统的使用。
(2)任务异步处理
将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间。
比如在网上购物下了订单支付以后,系统其实也需要通知商家,然后库存系统要更新库存,但是订单支付成功的消息其实在支付以后就可以立刻响应给消费者,并不需要等库存系统更新了再响应,所以可以把用户支付完成的消息放在中间件里存起来,库存系统拿到这个消息再去做响应的处理。
(3)削峰填谷
如订单系统,在下单的时候就会往数据库写数据。但是数据库只能支撑每秒1000左右的并发写入,并发量再高就容易宕机。订单系统在低峰期的时候并发也就100多个,但是在高峰期时候,并发量会突然激增到5000以上,这个时候如果都写入数据库,数据库肯定卡死了。如果系统中加入了中间件,消息被中间件保存起来,然后系统就可以按照自己的消费能力来消费,比如每秒1000个消息,这样慢慢写入数据库,这样就不会卡死数据库了。这就是削峰。在高峰期过后的一段时间内,消费消息的速度还是会维持在1000QPS,直到消费完积压的消息,这就叫做填谷。
当然MQ也不是一点缺点都没有。
(1)系统稳定性降低
系统引入的外部依赖越多,系统稳定性越差。MQ作为一种服务,也会出现宕机的情况,一旦 MQ 宕机,就会对业务造成影响。如何保证MQ的高可用?
(2)系统复杂度提高
其次MQ 的加入大大增加了系统的复杂度,以前系统间是同步的远程调用,现在是通过 MQ 进行异步调用。如何保证消息没有被重复消费?怎么处理消息丢失情况?那么保证消息传递的顺序性?
(3)一致性问题
A 系统处理完业务,通过 MQ 给B、C、D三个系统发消息,如果 B 系统、C 系统处理成功,D 系统处理失败。如何保证消息数据处理的一致性?
3、消息中间件的分类
消息中间件要完成不同系统之间的通讯,必须要具备一些功能,比如最基本的通讯功能,消息中间件应该选择什么样的协议作为通讯协议?是否支持跨平台,是否支持不同系统不同语言开发?是否支持集群?是否具备持久化功能?对此,目前比较流行的消息中间件的功能整理如下:
4、消息中间件协议
要完成通信功能,绕不开的话题就是协议。现在流行的消息中间件都不是直接使用http协议,而是在最基本的TCP/IP协议基础上开发的另外一套协议。为什么不直接使用http协议呢?主要是因为http协议比较复杂,具有cookie,数据的加密解密,状态码,响应码等附加功能,而作为消息中间件,它负责数据传递、存储、分发就可以了,追求高性能,尽量简洁、快捷,就不需要这么复杂的协议和复杂的功能。另一个原因是大部分情况下http都是短链接,在实际交互过程中,一个请求到响应很可能会中断,中断以后就不会进行持久化,造成请求的丢失,不利于消息中间件的业务场景,所以就不会直接使用http协议作为消息中间件的协议。
常见的消息中间件协议有:openWire、AMQP、MQTT、kafka、OpenMessage协议等。
(1)AMQP(Advanced Message Queuing Protocol)
AMQP是高级消息队列协议。由摩根大通集团联合其他公司共同设计。是一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一 个开放标准,为面向消息的中间件设计。也是属于Spring家族的一个协议。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。AMQP是用Erlang语言开发的,Erlang的底层是C语言,大量应用于交换机,因为AMQP协议是用Erlang语言开发的,RabbitMQ是支持AMQP协议的,所以安装RabbitMQ的时候要安装Erlang。
特性:分布式事务支持、消息的持久化支持、高性能和高可靠的消息处理优势。
目前RabbitMQ、ActiveMQ都支持AMQP协议。
(2)MQTT(Message Queuing Telemetry Transport)
IBM 开放的一个即时通讯协议,物联网系统架构适用,轻量,结构简单,传输快,不支持事务,没有持久化设计适用计算能力有限,低带宽,网络不稳定
目前RabbitMQ、ActiveMQ都支持MQTT协议。不过RabbitMQ默认是关闭的
(3)OpenMessage协议
由阿里、雅虎、滴滴、Stremalio等公司共同参与创立的分布式消息中间件、流处理等领域的应用开发标准
特点:结构简单、解析速度块、支持事务和持久化设计
(4)Kafka协议
基于TCP/IP的二进制协议,消息内部通过长度来分割,由一些基本数据类型组成
特点:结构简单、解析速度快、无事务支持、有持久化设计
5、消息队列持久化
持久化就是指将数据写入磁盘,而不是写入内存,导致数据随服务器的断开而丢失,使数据能够永久保存。
各类消息中间件产品支持的持久化方式如下:
6、消息中间件的高可用和高可靠
完成通信协议和数据持久化后,消息中间件还需要具备高可用性和高可靠性。所谓高可用是指产品在规定的条件和时间内处于可执行规定功能状态的能力。当业务量增加,请求过大时,一台消息中间件服务器可能会触及硬件(CPU、内存、磁盘)的极限,一台消息服务器已经无法满足业务的需求,所以消息中间件必须支持集群部署,来达到高可用的目的。
集群模式1、Master-Slave主从共享数据的部署方式
生产者将消息发送到Master节点,所有的主机从机都连接这个消息队列共享这块数据区域,Master节点负责写入,一旦master挂掉,slave继续服务,形成高可用。缺点也很明显,master负责写入数据,一旦master挂掉,就无法写入数据了,只能读取数据。所以一般应用在小型项目上。注意这种方式是主从共享一块数据区域,从机不是主机的副本。
集群模式2、Master-Slave主从同步部署方式
这种模式写入消息同样在master主节点上,但主节点会同步数据到slave节点形成副本,和zookeeper或者redis主从机制类似,可以达到负载均衡的效果。如果消费者有多个,就可以到不同的节点去消费,但消息的拷贝和同步会占用很大带宽和网络资源,在rabbitmq中有使用到。
集群模式3、多主集群同步部署方式
和模式2的部署方式差不多,但在这种模式下从节点也可以写入数据
集群模式4、多主集群转发部署模式
上面多主集群同步的方式会形成多个数据副本,造成大量资源浪费,所以又衍生出了这种方式。比如插入的数据在broker1中,它会同时生成一个元数据,元数据并不是完整的数据,而是对源数据的描述和记录源数据的储存位置,这个元数据会被同步。如果消费者在broker2中进行消费,发现自己没有对应的数据时,就会根据元数据信息去对应的服务器中查询,然后返回消息信息。
集群模式5、Master-slave与Broker-cluster组合的方案
实现多主多从的热备机制来完成消息的高可用以及数据的热备机制,在生产规模达到一定阶段时,这种使用频率比较高。
总结上面的模式:要么消息共享,要么消息同步,要么元数据共享
高可靠机制:
高可靠是指系统可以无故障低持续运行,比如一个系统突然崩溃、报错、异常等并不影响线上业务的正常运行,出错几率极低,统称为高可靠。
在高并发业务场景中,如果不能保证系统的高可靠,造成的隐患和损失是非常严重。
为了保证高可靠,可以从两个方面考虑:
(1)消息的传输可靠:通过协议保证数据解析的正确性
(2)消息的存储可靠:通过持久化来保证消息的可靠。
7、RabbitMQ
7.1、RabbitMQ的架构
讲了这么多终于到RabbitMQ了。
2007年,Rabbit 技术公司基于 AMQP 标准开发的 RabbitMQ 1.0 发布。RabbitMQ 采用 Erlang 语言开发。Erlang 语言专门为开发高并发和分布式系统的一种语言,在电信领域使用广泛。
RabbitMQ的基础架构图如下:
RabbitMQ 中的相关概念:
Broker:接收和分发消息的应用,RabbitMQ Server就是 Message Broker
Virtual host:出于多租户和安全因素设计的,把 AMQP 的基本组件划分到一个虚拟的分组中,类似于网络中的 namespace 概念。当多个不同的用户使用同一个 RabbitMQ server 提供的服务时,可以划分出多个vhost,每个用户在自己的vhost 创建 exchange、queue 等
Connection:publisher/consumer 和 broker 之间的 TCP 连接
Channel:如果每一次访问 RabbitMQ 都建立一个Connection,在消息量大的时候建立 TCP Connection的开销将是巨大的,效率也较低。Channel 是在 connection 内部建立的逻辑连接,如果应用程序支持多线程,通常每个thread创建单独的 channel 进行通讯,AMQP method 包含了channel id 帮助客户端和message broker 识别 channel,所以 channel 之间是完全隔离的。Channel 作为轻量级的 Connection 极大减少了操作系统建立 TCP connection 的开销
Exchange:message 到达 broker 的第一站,根据分发规则,匹配查询表中的 routing key,分发消息到queue 中去。常用的类型有:direct (point-to-point), topic (publish-subscribe) andfanout (multicast)
Queue:消息最终被送到这里等待 consumer 取走
Binding:exchange 和 queue 之间的虚拟连接,binding 中可以包含 routing key。Binding 信息被保存到 exchange 中的查询表中,用于 message 的分发依据
7.2、安装
RabbitMQ是基于Erlang语言开发的,所以安装RabbitMQ的同时也要安装Erlang。
地址:https://www.rabbitmq.com/download.html
下载时要注意版本号的问题,RabbitMQ和Erlang的版本号需要对应:
下载rpm包并上传至虚拟机
安装步骤:
(1)安装依赖环境
yum install build-essential openssl openssl-devel unixODBC unixODBC-devel make gcc gcc-c++ kernel-devel m4 ncurses-devel tk tc xz
(2)检查glibc版本
如果glibc版本低于2.15,安装Erlang有可能报错
# 查看gblic版本号
strings /lib64/libc.so.6|grep GLIBC
# 如果glibc版本号低于2.15,执行下面命令
sudo yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make -y
(3)安装Erlang
rpm -ivh erlang-18.3-1.el7.centos.x86_64.rpm
# 检查是否安装成功,出现erlang版本号说明安装成功
erl -v
(4)安装socat
socat是一个多功能网络工具,rabbitMQ建立连接主要依赖这个工具
rpm -ivh socat-1.7.3.2-1.1.el7.x86_64.rpm --force --nodeps
(5)安装rabbitMQ
rpm -ivh rabbitmq-server-3.6.5-1.noarch.rpm
(7)启动rabbitMQ
# 启动rabbitMQ
systemctl start rabbitmq-server
# 查看rabbitMQ状态
systemctl status rabbitmq-server
# 停止rabbitMQ
systemctl stop rabbitmq-server
通过status查看状态,看到状态显示active(running)说明已经启动成功
7.3、图形化管理界面
RabbitMQ提供了一个图形化管理界面,可以看到当前MQ的状态。要进入图形化管理界面首先要开启插件:
rabbitmq-plugins enable rabbitmq_management
开启以后,会有一个默认用户名guest和默认密码guest,注意这个默认用户名和密码仅能在本机使用,不能用于远程。因为我的RabbitMQ是安装在虚拟机的,所以不能用这个用户名密码登录。
远程访问要添加账号和密码,并授权
(1)新增用户
rabbitmqctl add_user 用户名 密码
示例:
rabbitmqctl add_user admin 123456
(2)设置用户分配操作权限
rabbitmqctl set_user_tags 用户名 权限
示例:
rabbitmqctl set_user_tags admin administrator
用户级别如下:
administrator: 可以登录控制台,查看所有信息,对rabbitmq进行管理
- 最高权限
- 可以创建和删除virtual hosts
- 可以查看、创建和删除users
- 查看创建permissions
- 关闭所有用户的connections
monitoring: 监控者,可以登录控制台,查看所有信息
- 包含management所有的权限
- 罗列出所有的virtual hosts,包括不能登录的virtual hosts
- 查看其他用户的connections、channels信息
- 查看节点级别的数据如clustering、memory使用情况
- 查看所有virtual hosts的全局统计信息
policymaker: 策略制定者,可以登录控制台,指定策略
- 包含management所有的权限
- 查看、创建和删除自己的virtual hosts所属的policies和parameters信息
management: 普通管理员,查看自己相关节点的信息
- 列出自己可以通过AMQP登入的虚拟机
- 查看自己的虚拟机节点 virtual hosts的queues、exchanges和bingdings信息
- 查看和关闭自己的channels和connections
- 查看有关自己的虚拟机节点virtual hosts的统计信息。包括其他用户在这个节点virtual hosts中的活动信息
none: 不能访问plugin
(3)为用户添加资源权限
rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
现在用新的用户名密码登录 远程ip:15672 即可进入图形管理界面。
注:15672是管控台的端口号
(4)其他指令
# 更改用户名密码
rabbitmqctl change_password 用户名 新密码
# 查看用户清单
rabbitmqctl list_users
# 删除用户
rabbitmqctl delete_user 用户名
以上就是关于消息中间件的简介及RabbitMQ的安装,RabbitMQ提供了六种消息模式,这个将放到下一章写。