本系列课程参考于:
- https://www.kuangstudy.com/zl/rabbitmq
- https://www.bilibili.com/video/BV1dX4y1V73G
感谢分享!
1、什么是中间件?
1)概念
我国企业从20世纪80年代开始就逐渐进行信息化建设,由于方法和体系的不成熟,以及企业业务和市场需求的不断变化,一个企业可能同时运行着多个不同的业务系统,这些系统可能基于不同的操作系统、不同的数据库、异构的网络环境。现在的问题是,如何把这些信息系统结合成一个有机地协同工作的整体,真正实现企业跨平台、分布式应用。中间件便是解决之道,它用自己的复杂换取了企业应用的简单。
中间件(Middleware)是处于操作系统和应用程序之间的软件,也有人认为它应该属于操作系统中的一部分。人们在使用中间件时,往往是一组中间件集成在一起,构成一个平台(包括开发平台和运行平台),但在这组中间件中必须要有一个通信中间件,即 中间件 = 平台 + 通信,这个定义也限定了只有用于分布式系统中才能称为中间件,同时还可以把它与支撑软件和实用软件区分开来。
举例:
- RMI(Remote Method Invocations, 远程调用)
- Load Balancing(负载均衡,将访问负荷分散到各个服务器中)
- Transparent Fail-over(透明的故障切换)
- Clustering(集群,用多个小的服务器代替大型机)
- Back-end-Integration(后端集成,用现有的、新开发的系统如何去集成遗留的系统)
- Transaction事务(全局/局部)全局事务(分布式事务)局部事务(在同一数据库联接内的事务)
- Dynamic Redeployment(动态重新部署,在不停止原系统的情况下,部署新的系统)
- System Management(系统管理)
- Threading(多线程处理)
- Message-oriented Middleware面向消息的中间件(异步的调用编程)
- Component Life Cycle(组件的生命周期管理)
- Resource pooling(资源池)
- Security(安全)
- Caching(缓存)
2)为什么需要使用消息中间件?
具体地说,中间件屏蔽了底层操作系统的复杂性,使程序开发人员面对一个简单而统一的开发环境,减少程序设计的复杂性,将注意力集中在自己的业务上,不必再为程序在不同系统软件上的移植而重复工作,从而大大减少了技术上的负担。中间件带给应用系统的,不只是开发的简便、开发周期的缩短,也减少了系统的维护、运行和管理的工作量,还减少了计算机总体费用的投入。
3)中间件特点
为解决分布异构问题,人们提出了中间件(middleware)的概念。中间件是位于平台(硬件和操作系统)和应用之间的通用服务,如下图所示,这些服务具有标准的程序接口和协议。针对不同的操作系统和硬件平台,它们可以有符合接口和协议规范的多种实现。
也许很难给中间件一个严格的定义,但中间件应具有如下的一些特点:
- 满足大量应用的需要
- 运行于多种硬件和OS平台
- 支持分布计算,提供跨网络、硬件和OS平台的透明性的应用或服务的交互
- 支持标准的协议
- 支持标准的接口
由于标准接口对于可移植性和标准协议对于互操作性的重要性,中间件已成为许多标准化工作的主要部分。对于应用软件开发,中间件远比操作系统和网络服务更为重要,中间件提供的程序接口定义了一个相对稳定的高层应用环境,不管底层的计算机硬件和系统软件怎样更新换代,只要将中间件升级更新,并保持中间件对外的接口定义不变,应用软件几乎不需任何修改,从而保护了企业在应用软件开发和维护中的重大投资。
简单说:中间件有个很大的特点,是脱离于具体设计目标,而具备提供普遍独立功能需求的模块。这使得中间件一定是可替换的。如果一个系统设计中,中间件是不可替换的,不是架构、框架设计有问题,那么就是这个中间件,在别处可能是个中间件,在这个系统内是引擎。
中间件就是设计模式中的
外观模式
2、中间件技术及架构
1)知识图谱
2)单体架构
在企业开发的中,大部分的初期架构都采用的是单体架构的模式进行架构,而这种架构的典型的特点:就是把所有的业务和模块,源代码,静态资源文件等都放在一个一工程中,如果其中的一个模块升级或者迭代发生一个很小变动都会重新编译和重新部署项目。 这种的架构存在的问题就是:
- 耦合度太高
- 运维的成本过高
- 不易维护
- 服务器的成本高
- 升级架构的复杂度也会增大
3)分布式架构
通俗一点:就是一个请求由服务器端的多个服务(服务或者系统)协同处理完成
和单体架构不同的是,单体架构是一个请求发起jvm调度线程(确切的是tomcat线程池)分配线程Thread来处理请求直到释放,而分布式是系统是:一个请求是由多个系统共同来协同完成,jvm和环境都可能是独立的。
单体架构就像建设一个小房子,很快就能够搞定,如果你要建设一个鸟巢或者大型的建筑,你就必须是各个环节的协同和分布,这样也是项目发展到后期的时候要去部署和思考的问题。
存在问题
- 学习成本高,技术栈过多
- 运维成本和服务器成本增高
- 人员的成本也会增高
- 项目的负载度也会上升
- 面临的错误和容错性也会成倍增加
- 占用的服务器端口和通讯的选择成本高
- 安全性的考虑和因素逼迫可能选择RMI/MQ相关的服务器端通讯
好处
- 服务系统的独立,占用的服务器资源减少和占用的硬件成本减少,确切的说是:可以合理的分配服务资源,不造成服务器资源的浪费
- 系统的独立维护和部署,耦合度降低,可插拔性
- 系统的架构和技术栈的选择可以变的灵活(而不是单纯的选择java)
- 弹性的部署,不会造成平台因部署造成的瘫痪和停服的状态。
3、消息中间件的分布式系统架构
从上图中可以看出来,消息中间件是
- 利用可靠的消息传递机制进行不同系统间的通讯
- 通过提供消息传递和消息的排队机制,可以在分布式系统环境下扩展进程间的通讯
消息中间件应用场景
- 跨系统数据传递
- 高并发的流量削峰
- 数据的分发和异步处理
- 大数据分析与传递
- 分布式事务
比如请求并发过多的时候:有10W的并发请求下订单,可以在这些订单入库之前,先把订单请求堆积到消息队列中,让它稳健可靠的入库和执行
常见的消息中间件
ActiveMQ、RabbitMQ、Kafka、RocketMQ等。
消息中间件的本质及设计
它是一种接受数据,接受请求、存储数据、发送数据等功能的技术服务。
MQ消息队列:负责数据的接收,存储和传递,所以性能要高于普通服务和技术。
谁来生产消息,存储消息和消费消息呢?
消息中间件的核心组成部分
- 消息的协议
- 消息的持久化机制
- 消息的分发策略
- 消息的高可用,高可靠
- 消息的容错机制
4、消息队列协议
1)什么是协议?
消息中间件负责数据的传递,存储,分发消费三个部分,数据的存储和分发的过程中肯定要遵循某种约定俗成的规范,是采用底层的TCP/IP,UDP协议还是其他的自己去构建等,而这些约定俗成的规范就称之为:协议。
所谓协议是指:
- 计算机底层操作系统和应用程序通讯时共同遵守的一组约定,只有遵循共同的约定和规范,系统和底层操作系统之间才能相互交流。
- 协议和一般的网络应用程序不同,它主要负责数据的接受和传递,所以性能比较的高。
- 协议要求对数据格式和计算机之间交换数据都必须严格遵守规范。
2)网络协议的三要素
语法
是用户数据与控制信息的结构与格式,以及数据出现的顺序语义
是解释控制信息每个部分的意义。它规定了需要发出何种控制信息,以及完成动作与做出什么样的响应时序
是对事件发生顺序的详细说明
比如:MQ发送一个信息,是以什么数据格式发送到队列中,然后每个部分的含义是什么,发送完毕以后的执行动作,以及消费者消费消息的动作,消费完毕的响应结果和反馈是什么,然后按照对应的执行顺序进行处理。
http请求协议:
- 语法:http规定了请求报文和响应报文的格式。
- 语义:客户端主动发起请求称之为请求。(这是一种定义,同时你发起的是post/get请求)
- 时序:一个请求对应一个响应。(一定先有请求再有响应,这个是时序)
消息中间件采用的并不是http协议,而常见的消息中间件协议有:OpenWire
、AMQP
、MQTT
、Kafka
、OpenMessage
协议。
为什么消息中间件不直接使用http协议呢?
- 因为http请求报文头和响应报文头是比较复杂的,包含了cookie,数据的加密解密,状态码,响应码等附加的功能,但是对于一个消息而言,并不需要这么复杂,也没有这个必要性,它其实就是负责数据传递,存储,分发就行,一定要追求的是高性能。尽量简洁,快速。
- 大部分情况下http都是短链接,在实际的交互过程中,一个请求到响应很有可能会中断,中断以后就不会进行持久化,就会造成请求的丢失。这样就不利于消息中间件的业务场景,因为消息中间件可能是一个长期获取消息的过程,出现问题和故障要对数据或消息进行持久化等,目的是为了保证消息和数据的高可靠和稳健的运行
3)AMQP协议
AMQP:(全称:Advanced Message Queuing Protocol) 是高级消息队列协议。
由摩根大通集团联合其他公司共同设计。是一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。Erlang中的实现有RabbitMQ等。
特点:
- 分布式事务支持
- 消息的持久化支持
- 高性能和高可靠的消息处理优势
支持者:
4)MQTT协议
MQTT协议:(Message Queueing Telemetry Transport)是IBM开放的一个即时通讯协议,物联网系统架构中的重要组成部分。
特点:
- 轻量
- 结构简单
- 传输快,不支持事务
- 没有持久化设计
应用场景:
- 计算能力有限
- 低带宽
- 网络不稳定
5)OpenMessage协议
OpenMessage 是近几年由阿里、雅虎和滴滴出行、Stremalio等公司共同参与创立的分布式消息中间件、流处理等领域的应用开发标准。
特点:
- 结构简单
- 解析速度快
- 支持事务和持久化设计
支持者:
6)Kafka协议
Kafka 协议是基于TCP/IP的二进制协议。消息内部是通过长度来分割,由一些基本数据类型组成。
特点:
- 结构简单
- 解析速度快
- 无事务支持
- 有持久化设计
支持者:
5、消息队列持久化
就是将数据存入磁盘,而不是存在内存中随服务器重启断开而消失,使数据能够永久保存。
常见的持久化方式
存储方式 | ActiveMQ | RabbitMQ | Kafka | RocketMQ |
---|---|---|---|---|
文件存储 | 支持 | 支持 | 支持 | 支持 |
数据库 | 支持 | / | / | / |
6、消息的分发策略
MQ消息队列有如下几个角色:
- 生产者
- 消息存储者
- 消费者
那么生产者生成消息以后,MQ进行存储,消费者是如何获取消息的呢?
一般获取数据的方式无外乎 推(push)
或者 拉(pull)
两种方式,典型的 Git 就有推拉机制,我们发送的http请求就是一种典型的拉取数据库数据返回的过程。
消息队列 MQ 是一种推送的过程,而这些推机制会适用到很多的业务场景,也有很多对应推机制策略。
场景分析一
如:在APP上下了一个订单,我们的系统和服务很多,如何得知这个消息被那个系统或者服务进行消费,那这个时候就需要一个分发的策略。这就需要消费策略。或者称之为消费的方法论。
场景分析二
在发送消息的过程中可能会出现异常,或者网络的抖动,故障等等原因,造成消息的无法消费。比如:用户在下订单,MQ接收消息,这时订单系统出现故障,导致用户支付失败,那么这个时候就需要消息中间件支持消息重试机制策略。也就是支持:出现问题和故障的情况下,消息不丢失还可以进行重发。
消息分发策略的机制和对比
分发机制 | ActiveMQ | RabbitMQ | Kafka | RocketMQ |
---|---|---|---|---|
发布订阅 | 支持 | 支持 | 支持 | 支持 |
轮询分发 | 支持 | 支持 | 支持 | / |
公平分发 | / | 支持 | 支持 | / |
重发 | 支持 | 支持 | / | 支持 |
消息拉取 | / | 支持 | 支持 | 支持 |
7、消息队列高可用和高可靠
1)什么是高可用机制?
所谓高可用:是指产品在规定的条件和规定的时刻或时间内处于可执行规定功能状态的能力。
当业务量增加时,请求也过大,一台消息中间件服务器的会触及硬件(CPU,内存,磁盘)的极限,一台消息服务器已经无法满足业务的需求,所以消息中间件必须支持集群部署。来达到高可用的目的。
2)Master-slave主从共享数据
生产者将消息发送到Master节点,所有的从节点都连接这个消息队列 共享
这块数据区域,Master节点负责写入,一旦Master挂掉,slave节点继续服务,从而形成高可用。
3)Master-slave主从同步部署
这种模式写入消息同样在Master主节点上,但是主节点会 同步
数据到slave节点形成副本,和zookeeper或者redis主从机制很类同。这样可以达到负载均衡的效果,如果消费者有多个,这样就可以去不同的节点进行消费,消息的拷贝和同步会占用很大的带宽和网络资源。在后续的rabbitmq中会有使用。
4)多主集群同步部署
和上面的区别不是特别的大,但是它的写入可以往任意节点去写入
5)多主集群转发部署
如果插入的数据是broker-1中,元数据信息会存储数据的相关描述和记录存放的位置(队列)。
它会对描述信息也就是元数据信息进行同步,如果消费者在broker-2中进行消费,发现没有对应的消息,可以从对应的元数据信息中去查询,然后返回对应的消息信息。
场景:如黄牛卖演唱会门票,第一个黄牛没有顾客要的票,但是他会去联系其他的黄牛询问,如果有,就告诉顾客有。
6)M-s与B-c组合方案
实现多主多从的热备机制来完成消息的高可用以及数据的热备机制,在生产规模达到一定阶段的时候,这种使用的频率比较高。
集群模式最终目的都是为了保证:消息服务器不会挂掉,出现了故障依然可以保证消息服务继续使用。
总结:
- 要么消息共享
- 要么消息同步
- 要么元数据共享
7)什么是高可靠机制?
所谓高可用:是指系统可以无故障地持续运行。
比如:一个系统突然崩溃,报错,异常等等并不影响线上业务的正常运行,出错的几率极低,就称之为:高可靠。
在高并发的业务场景中,如果不能保证系统的高可靠,那造成的隐患和损失是非常严重的。
如何保证中间件消息的可靠性呢?可以从两个方面考虑:
- 消息的传输:通过协议来保证系统间数据解析的正确性。
- 消息的存储:通过持久化来保证消息的可靠性。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/70413.html