1、什么是中间件?
中间件是处于操作系统和应用程序之间的软件。在使用中间件时,往往是一组中间件集成在一起,构成一个平台(包括开发平台和运行平台),但在这组中间件中必须要有一个通信中间件。即中间件=平台+通信,这个定义也限定了只有用于分布式系统才能称为中间件,同时还可以把它与支撑软件和实用软件区分开来。
1.1 特性
- 能够进行通讯
- 支持高可用
- 数据持久性
- -作为使用者的话,可以屏蔽底层操作系统的复杂性;如果作为开发者的话,就必须要了解tcp/ IP协议,以及如何完成底层操作系统的沟通、如何去使用的多线程
- 使用中间件技术可以屏蔽应用程序架构之间的局限性。比如用户系统使用java开发,订单系统使用go开发,支付系统通过php开发,通过使用中间件可以把这些技术给串联起来,从而达到一个更加稳健、缩短开发周期,也可以减少我们的维护成本的一个目的。
1.2 什么时候使用中间件技术
在项目的架构和重构中,使用任何技术和架构的改变我们都需要谨慎斟酌和思考。也就是说,但选择这些技术的时候,要思考这些技术是否需要用到,具不具备这些特征。如果是一个刚创建的公司建议还是使用单体架构,最多加个缓存中间件即可,不要盲目追求新或者所谓的高性能,而追求的背后一定是业务的驱动和项目的驱动,因为一旦追求意味着你的学习成本,公司的人员架构以及服务器成本、维护和运维成本都会提高,关键的还是自己花时间和花精力去探讨和研究。
2、中间件技术及架构的概述
2.1 分布式消息中间件
- activemq
- rabbitmq
- Kafka
- rocketmq
2.1.1 场景
- 消息中间件监控数据
- 异步数据传输场景
- 削峰填谷场景
- 任务调度场景
- 海量数据同步场景
- 分布式事务场景
- 日志管理场景
- 大数据分析场景
2.2 负载均衡中间件
- nginx
- lvs负载均衡软件
- keepalive
- CDN
2.3 缓存中间件
- memcache
- redis
2.4 数据中间件
- my cat
- shardingJdbc
3、基于消息中间件的分布式系统的结构
3.1 单体架构
- 耦合度太高。所以业务和模块都在一个项目中,如果一个模块出现问题,那么就需要对所有模块进行重新编译和发布
- 运维成本过高。
- 不易维护
- 服务器成本高
- 以及升级架构的复杂度也会增大
通俗说:就是一个请求由服务器端的多个模块协同处理完成 和单体架构不同的是,单体架构是一个请求发起jvm调度线程(确切的是tomcat线程池)分配线程thread来处理请求直到释放,而分布式系统是:一个请求由多个系统共同来协同完成的,jvm和环境可能是独立。用生活中来举例的话,单体架构就可说是一个小房子很快就能搞定,如果你想建设一个鸟巢或大的建筑,就必须要各个环节的协同和分布,这样的目的也是项目发展到后期的时候要去部署和思考的问题
缺点
- 学习成本高,技术栈很多
- 运维成本和服务器成本增高
- 人员的成本也会提高
- 项目的负载度也会上升
- 面临的错误和容错性也会成倍增加
- 占用的服务器端口和通讯的选择的成本高
- 安全性的考虑和因素逼迫可能选择RMI/MQ相关的服务器端通讯
优点
- 服务系统的独立,占用的服务器资源减少和占用的硬件成本减少,确切的说是:可以合理的分配服务资源,不造成服务器资源的浪费
- 系统的独立维护和部署,耦合度降低,可插拔性
- 系统的架构和技术栈的选择可以变得灵活(而不是单纯的选择java)
- 弹性的部署,不会造成平台因部署造成的瘫痪和停服的状态
2.6 选择中间件所需特性
- 是否能够进行通讯
- 是否能够可持久化
- 是否能够支持高可用
- 是否支持跨平台,也即为能够屏蔽系统之间的语言的差异
所以总结:消息中间件就是利用可靠的消息传递机制进行系统间的通讯,通过提供消息传递和消息的排队机制,它可以在分布式系统环境下扩展进程间的通讯。
3.3 消息中间件应用场景
- 跨系统数据传递
- 高并发的流量削峰
- 数据的分发和异步处理
- 大数据分析与传递
- 分布式事务
比如你有一个数据要进行迁移或者请求并发过多的时候,比如你有10w的并发请求下订单,我们可以在这些订单入库之前,把订单请求堆积到消息队列中,让它稳健的入库和执行。
3.4 消息中间件的本质及设计
3.4.1 本质
它是一种接受数据、接受请求、存储数据、发送数据的一种技术服务。 MQ消息队列:负责数据的传送和接受,存储,所以性能要高于普通服务和技术。
3.4.2 消息中间件的核心组成部分
- 消息的协议
- 消息的持久化机制
- 消息的分发策略
- 消息的高可用、高可靠
- 消息的容错机制
2、消息队列协议
2.1 什么是协议
我们知道消息中间件其实就是负责数据的传递、存储和分发消费。数据存储和分发的过程中肯定要遵守某种约定俗成的协议,至于你是采用底层的TCP/IP,还是UDP协议还是其他的取决于构建,而这些约定俗成的规范称之为协议。
总结:协议就是系统之间共同约定的规范。
2.2 网络协议三要素
1、语法:语法是用户数据与控制信息的结构与格式以及数据出现顺序
2、语义:语义是解释控制信息每个部分的意义。它规定了需要发出何种控制信息,以及完成的动作与做出什么样的响应
3、时序:时序是对事件发生顺序的详细说明
比如用MQ发送一个信息,是以什么数据格式发送到队列中,然后每个部分的含义是什么,发送完毕以后执行的动作以及消费者消费消息的动作,消费完毕的响应结果和反馈是什么,然后按照对应的执行顺序进行处理。如果还是不理解:大家每天都在接触的http请求协议:
- 1.语法:http规定了请求报文和响应报文的格式
- 2.语义:客户端主动发请求称之为请求(这是一种定义,同时你发起的是get/post请求)
- 3.时序:一个请求对应一个响应(一定要先有请求再有响应,这个是时序)
而消息中间件采用的并不是http协议,而常见的消息中间件协议有:OpenWire、AMQP、MQIT、Kafka、OpenMessage协议。
面试题:为什么消息中间件不直接使用http协议?
1、因为http请求报文头和响应报文头是比较复杂的,包含了cookie,数据的加密解密,状态码,响应码等附加的功能,但是对于一个消息而言,我们并不需要这么复杂,也没有这个必要性,它其实就是负责数据的传递、存储和分发就可以,一定要追求高性能,尽量简洁、快捷
2、大部分情况下http大部分是短链接,也即为在实际的交互过程中,一个请求的响应可能被中断,中断以后就不会进行持久化,就会造成请求丢失。这样就不利于消息中间件的业务场景。因为消息中间件可能是一个长期的获取消息的过程,出现问题和故障要对数据或消息进行持久化等,目的是为了保证消息和数据的高可靠和稳定的运行。 也即使用http协议请求如果被中断的话,不会进行数据的持久化操作,数据会被丢失。
3.1 AMQP协议
AMQP:(全称:Advanced Message Queuing Protocol)是高级消息队列协议。是一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息中间件设计。基于此协议客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。Erlang中的实现有rabbitmq等
特性:
1、分布式事务支持
2、消息的持久化支持
3、高性能和高可用的消息处理优势
|