一、中间件
什么是中间件
- 中间件(Middleware)是处于操作系统和应用程序之间的软件,也有人认为它应该属于操作系统中的一部分。人们在使用中间件时,往往是一组中间件集成在一起,构成一个平台(包括开发平台和运行平台),但在这组中间件中必须要有一个通信中间件,即中间件+平台+通信,这个定义也限定了只有用于分布式系统中才能称为中间件,同时还可以把它与支撑软件和使用软件区分开来。
二、消息中间件(MOM)
消息中间件(MOM),用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信
。
什么是MQ?
- MQ(message queue),从字面意思上看,本质是个队列,FIFO先入先出,只不过队列中存放的内容是message而已,还是
一种跨进程的通信机制,用于上下游传递消息
。在互联网架构中,MQ是一种非常常见的上下游“逻辑解耦+物理解耦”的消息通信服务。使用了MQ之后,消息发送上游只需要依赖MQ,不用依赖其他服务。 - MQ负责两个系统之间传递消息,这
两个系统可以是异构
的,处于不同硬件、不同操作系统、用不同语言编写,只需要简单配置、以及简单的调用几个MQ的API,就可以互相通讯,你不必考虑底层系统和网络的复杂性,MQ能够应付多种异常情况,例如网络阻塞、临时中断等等; - 消息队列主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。使用较多的消息队列有ActiveMQ,RocketMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ等,部分 数据库 如 Redis、MySQL 以及 phxsql 也可实现消息队列的功能。
消息中间件的应用场景:
- 系统解耦
- 交互系统之间没有直接的调用关系,只是通过消息传输,故系统侵入性不强,耦合度低。
- 将消息写入消息队列,需要消息的系统自己从消息队列中订阅,从而系统A不需要做任何修改。
- 跨系统数据传递
- 高并发的流量削峰
- 并发量大的时候,所有的请求直接怼到数据库,造成数据库连接异常。系统A慢慢的按照数据库能处理的并发量,从消息队列中慢慢拉取消息。在生产中,这个短暂的高峰期积压是允许的,假如消息队列的长度超过最大数量,则直接抛弃用户请求或跳转到错误页面
- 数据的分发和异步处理(就是并发处理)
- 将消息写入消息队列,非必要的业务逻辑以异步的方式运行,加快响应速度。
- 日志
- 解决大量日志传输的问题。日志采集:负责日志数据采集,定时写受写入Kafka队列;Kafka消息队列:负责日志数据的接收,存储和转发;日志处理应用:订阅并消费kafka队列中的日志数据 。
- 解决大量日志传输的问题。日志采集:负责日志数据采集,定时写受写入Kafka队列;Kafka消息队列:负责日志数据的接收,存储和转发;日志处理应用:订阅并消费kafka队列中的日志数据 。
- 消息通讯
- 消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实现点对点消息队列,或者聊天室(发布订阅通讯)等,
点对点通讯
发布/订阅通讯
消息中间件的本质及设计:
- 它是一种接受数据,接受请求、存储数据、发送数据等功能的技术服务。
消息中间件的核心组成部分:
- 消息的协议
- 消息的持久化机制
- 消息的分发策略
- 消息的高可用,高可靠
- 消息的容错机制
消息中间件订阅模式
1. 点对点模式
特点:消息被消费以后,Queue中不再有存储,所以消息消费者不可能消费到已经被消费的消息。Queue支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费
;Queue实现了负载均衡,当没有消费者可用时,这个消息会被保存直到有一个可用的消费者
。
2. 发布/订阅模式(也称广播模式)
特点:消息被一个订阅者消费后,并没有消失,而是储存在Topic中
,供所有的订阅者消费。
两者区别:这两种模式主要区别或解决的问题就是发送到队列的消息能否重复消费
3. 推拉模型(根据消费者获取消息的方式区分)
对于消费者而言有两种方式从消息中间件获取消息,即push和pull:
①Push方式:由消息中间件主动地将消息推送给消费者,这种方式可以尽快的将消息发给消费者。
②Pull方式:由消费者主动向消息中间件拉取消息,这种方式相比push方式会稍微增加消息的到达消费者的时间。
消息队列协议
- 消息中间件负责数据的传递,存储,和分发消费三个部分,数据的存储和分发的过程中肯定要遵循某种约定成俗的规范,你是采用底层的TCP/IP,UDP协议还是其他的自己取构建等,而这些约定成俗的规范就称之为:协议。
网络协议的三要素
- 语法:语法是用户数据与控制信息的结构与格式以及数据出现的顺序。
- 语义:语义是解释控制信息每个部分的意义。它规定了需要发出何种控制信息以及完成的动作与做出什么样的响应。
- 时序:时序是对事件发生顺序的详细说明。
比如MQ发送一个信息,是以什么数据格式发送到队列中,然后每个部分的含义是什么,发送完毕以后的执行的动作,以及消费者消费消息的动作,消费完毕的响应结果和反馈是什么,然后按照对应的执行顺序进行处理。如果你还是不理解;大家每天都在接触的http请求协议:
- 语法: http规定了请求报文和响应报文的格式。
- 语义:客户端主动发起请求称之为请求。
- 时序:一个请求对应一个响应。(一定是先有请求再有响应,这个是时序)
而消息中间件采用的并不是http协议,而常见的消息中间件协议有:OpenWire、AMQP、MQTT、Kafka,OpenMessage协议。各协议特点
为什么消息中间件不直接使用 http协议?
- 因为 http请求报文头和响应报文头是比较复杂的,包含了Cookie,数据的加密解密,状态码,响应码等附加的功能,但是对于一个消息而言,我们并不需要这么复杂,也没有这个必要性,它其实就是负责数据传递,存储,分发就行,一定要追求的是高性能。尽量简洁,快速。
- 大部分情况下 http大部分都是
短链接
,在实际的交互过程中,一个请求到响应都很有可能会中断,中断以后就不会执行持久化,就会造成请求的丢失。这样就不利于消息中间件的业务场景,因为消息中间件可能是一个长期的获取信息的过程,出现问题和故障要对数据或消息执行持久化等,目的是为了保证消息和数据的高可靠和稳健的运行。
消息队列持久化
简单来说就是将数据存入磁盘,而不是存在内存中随服务器重启断开而消失,使数据能够永久保存。
常见消息队列对持久化的支持
消息的分发策略
MQ消息队列有如下几个角色:
- 生产者
- 存储消息
- 消费者
消息的重试机制策略
消息中间件就必须支持消息重试机制策略。也就是支持:出现问题和故障的情况下,消息不丢失还可以进行重发。常见消息队列的消息分发策略的机制和对比:
什么是高可靠?
所谓高可靠是指:是指系统可以无故障地持续运行,比如一个系统突然崩溃,报错,异常等等并不影响线上业务的正常运行,出错的几率极低,就称之为:高可靠。
在高并发的业务场景中,如果不能保证系统的高可靠,那造成的隐患和损失是非常严重的。如何保证中间件消息的可靠性呢?可以从两个方面考虑:
- 消息的传输可靠:通过协议来保证系统间数据解析的正确性。
- 消息的存储可靠:通过持久化来保证消息的可靠性。
三、RPC(Remote Procedure Call Protocol).
RPC与MOM对比
跨语言跨平台,面向过程
RPC与MOM对比
RPC系统结构:
+----------+ +----------+
| Consumer | <=> | Provider |
+----------+ +----------+
Consumer调用的Provider提供的服务。
Message Queue系统结构:
+--------+ +-------+ +----------+
| Sender | <=> | Queue | <=> | Receiver |
+--------+ +-------+ +----------+
Sender发送消息给Queue;Receiver从Queue拿到消息来处理。
Message Queue是异步单向的消息,发送消息设计成是不需要等待消息处理的完成。而RPC是同步调用,对于要等待返回结果/处理结果的场景,RPC非常适合(RPC也可以是异步调用),由于等待结果,Consumer(Client)会有线程消耗。
RPC的组成与调用过程
对RPC的简单理解
【RPC】RPC基本介绍
参考博文:
消息中间件(MQ)的相关知识
RPC和MQ对比及其适用/不适用场合