消息中间件介绍

文章目录

一、消息中间件概念

    *对消息中间件的解释:面向消息的系统(消息中间件)是在分布式系统中完成消息的发送和接收的基础软件。
    消息中间件也可以称消息队列,是指用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息队列模型,可以在分布式环境下扩展进程的通信。
    异步处理、流量削峰、限流、缓冲、排队、最终一致性、消息驱动等需求的场景都可以使用消息中间件。

二、主流消息中间件及选型

    当前业界比较流行的开源消息中间件包括:ActiveMQ、RabbitMQ、RocketMQ、Kafka、 ZeroMQ等,其中应用最为广泛的要数RabbitMQ、RocketMQ、Kafka这三款。

RabbitMQ:
    RabbitMQ开始是用在电信业务的可靠通信的,也是少有的几款支持AMQP协议的产品之一。
优点:

  1. 轻量级,快速,部署使用方便
  2. 支持灵活的路由配置。RabbitMQ中,在生产者和队列之间有一个交换器模块。根据配置的路
    由规则,生产者发送的消息可以发送到不同的队列中。路由规则很灵活,还可以自己实现。
  3. RabbitMQ的客户端支持大多数的编程语言。

缺点:

  1. 如果有大量消息堆积在队列中,性能会急剧下降
  2. RabbitMQ的性能在Kafka和RocketMQ中是最差的,每秒处理几万到几十万的消息。如果应
    用要求高的性能,不要选择RabbitMQ。
  3. RabbitMQ是Erlang开发的,功能扩展和二次开发代价很高。

RocketMQ
    RocketMQ是一个开源的消息队列,使用java实现。借鉴了Kafka的设计并做了很多改进。 RocketMQ主要用于有序,事务,流计算,消息推送,日志流处理,binlog分发等场景。经过了历次的 双11考验,性能,稳定性可可靠性没的说。RocketMQ几乎具备了消息队列应该具备的所有特性和功能。
优点:

  1. java开发,阅读源代码、扩展、二次开发很方便。
  2. 对电商领域的响应延迟做了很多优化。在大多数情况下,响应在毫秒级。如果应用很关注响应时 间,可以使用RocketMQ。
  3. 性能比RabbitMQ高一个数量级,每秒处理几十万的消息。

缺点:

  1. 跟周边系统的整合和兼容不是很好。

Kafka
    Kafka的可靠性,稳定性和功能特性基本满足大多数的应用场景。跟周边系统的兼容性是数一数二的,尤其是大数据和流计算领域,几乎所有相关的开源软件都支持 Kafka。
优缺点:

  1. 高效,可伸缩,消息持久化。支持分区、副本和容错。
  2. Kafka是Scala和Java开发的,对批处理和异步处理做了大量的设计,因此Kafka可以得到非常高的 性能。它的异步消息的发送和接收是三个中最好的,但是跟RocketMQ拉不开数量级,每秒处理几十万的消息。
  3. 如果是异步消息,并且开启了压缩,Kafka最终可以达到每秒处理2000w消息的级别。 但是由于是异步的和批处理的,延迟也会高,不适合电商场景。

三、消息中间件应用场景及解决方案

电商秒杀案例
    比如6.18,活动从0:00开始,仅限前 200 名,秒杀即将开始时,用户会疯狂刷新 APP或者浏览器来 保证自己能够尽早的看到商品。
    当秒杀开始前,用户在不断的刷新页面,系统应该如何应对高并发的读请求呢? 在秒杀开始时,大量并发用户瞬间向系统请求生成订单,扣减库存,系统应该如何应对高并发的写请求呢?

如何应对高并发的读请求:

  1. 使用缓存策略将请求挡在上层中的缓存中
  2. 能静态化的数据尽量做到静态化
  3. 加入限流(比如对短时间之内来自某一个用户,某一个IP、某个设备的重复请求做丢弃处理)

如何应对高并发的写请求:
    生成订单,扣减库存,用户这些操作不经过缓存直达数据库。如果在 1s内,有 1 万个数据连接同 时到达,系统的数据库会濒临崩溃。如何解决这个问题呢?我们可以使用消息队列。

消息队列的作用:

  1. 削去秒杀场景下的峰值写流量——流量削峰
  2. 通过异步处理简化秒杀请求中的业务流程——异步处理
  3. 解耦,实现秒杀系统模块之间松耦合——解耦

流量削峰
    将秒杀请求暂存于消息队列,业务服务器响应用户“秒杀结果正在处理中…”,释放系统资源去处理其它用户的请求。
    削峰填谷,削平短暂的流量高峰,消息堆积会造成请求延迟处理,但秒杀用户对于短暂延迟有一定容忍度。
    秒杀商品有 1000 件,处理一次购买请求的时间是 500ms,那么总共就需要 500s 的时间。这时你部署10 个队列处理程序,那么秒杀请求的处理时间就是 50s,也就是说用户需要等待 50s 才可以看到秒杀的结果,这是可以接受的。这时会并发 10 个请求到达数据库,并不会对数据库造成很大的压力。

异步处理
    先处理主要的业务,异步处理次要的业务。 如主要流程是生成订单、扣减库存;次要流程比如购买成功之后会给用户发优惠券,增加用户的积分。
    此时秒杀只要处理生成订单,扣减库存的耗时,发放优惠券、增加用户积分异步去处理了。

实现秒杀系统模块之间松耦合
    将秒杀数据同步给数据团队,有两种思路:

  1. 使用 HTTP 或者 RPC 同步调用,即提供一个接口,实时将数据推送给数据服务。 系统的耦合度高,如果其中一个服务有问题,可能会导致另一个服务不可用。
  2. 使用消息队列 将数据全部发送给消息队列,然后数据服务订阅这个消息队列,接收数据进行处理。

四、JMS规范和AMQP协议讲解

JMS经典模式详解:
    JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间 件(MOM,Message oriented Middleware)的API,用于在两个应用程序之间,或分布式系统中发送 消息,进行异步通信。与具体平台无关的API,绝大多数MOM提供商都支持。

JMS模式
Java消息服务应用程序结构支持两种模式:

  1. 点对点也叫队列模式
  2. 发布/订阅模式

    点对点或队列模式:下一个生产者向一个特定的队列发布消息,一个消费者从该队列中读取消息。这里,生产者知道消费者的队列,并直接将消息发送到消费者的队列,概括为:
    1)一条消息只有一个消费者获得
    2)生产者无需在接收者消费该消息期间处于运行状态,接收者也同样无需在消息发送时处于运行状态。
    3)每一个成功处理的消息要么自动确认,要么由接收者手动确认。

发布/订阅模式:
    支持向一个特定的主题发布消息。
    0或多个订阅者可能对接收特定消息主题的消息感兴趣。
    发布者和订阅者彼此不知道对方。
    多个消费者可以获得消息

在发布者和订阅者之间存在时间依赖性:
    发布者需要建立一个主题,以便客户能够订阅。
    订阅者必须保持持续的活动状态以接收消息,否则会丢失未上线时的消息。
    对于持久订阅,订阅者未连接时发布的消息将在订阅者重连时重发。

AMQP协议剖析
    AMQP全称高级消息队列协议(Advanced Message Queuing Protocol),是一种标准,类似于JMS,兼容JMS协议。目前RabbitMQ主流支持AMQP 0-9-1,3.8.4版本支持AMQP 1.0。
消息中间件介绍

AMQP中的概念
    Publisher:消息发送者,将消息发送到Exchange并指定RoutingKey,以便queue可以接收到指定的消息。
    Consumer:消息消费者,从queue获取消息,一个Consumer可以订阅多个queue以从多个queue中接收消息。
    Server:一个具体的MQ服务实例,也称为Broker。
    Virtual host:虚拟主机,一个Server下可以有多个虚拟主机,用于隔离不同项目,一个Virtual host通常包含多个Exchange、Message Queue。
    Exchange:交换器,接收Producer发送来的消息,把消息转发到对应的Message Queue中。
    Routing key:路由键,用于指定消息路由规则(Exchange将消息路由到具体的queue中),通常需要和具体的Exchange类型、Binding的Routing key结合起来使用。
    Bindings:指定了Exchange和Queue之间的绑定关系。Exchange根据消息的Routing key和Binding配置(绑定关系、Binding、Routing key等)来决定把消息分派到哪些具体的queue中。这依 赖于Exchange类型。
    Message Queue:实际存储消息的容器,并把消息传递给最终的Consumer。

AMQP 传输层架构概述
    AMQP是一个二进制的协议,信息被组织成数据帧,有很多类型。数据帧携带协议方法和其他信 息。所有数据帧都拥有基本相同的格式:帧头,负载,帧尾。数据帧负载的格式依赖于数据帧的类型。
    我们假定有一个可靠的面向流的网络传输层(TCP/IP或等价的协议)。
    在一个单一的socket连接中,可能有多个相互独立的控制线程,称为“channel”。每个数据帧使用 通道号码编号。通过数据帧的交织,不同的通道共享一个连接。对于任意给定通道,数据帧严格按照序列传输。
    我们使用小的数据类型来构造数据帧,如bit,integer,string以及字段表。数据帧的字段做了轻微的封装,不会让传输变慢或解析困难。根据协议规范机械地生成成数据帧层相对简单。
    线级别的格式被设计为可伸缩和足够通用,以支持任意的高层协议(不仅是AMQP)。我们假定 AMQP会扩展,改进以及随时间的其他变化,并要求wire-level格式支持这些变化。

AMQP 使用的数据类型
    Integers(数值范围1-8的十进制数字):用于表示大小,数量,限制等,整数类型无符号 的,可以在帧内不对齐。
    Bits(统一为8个字节):用于表示开/关值。
    Short strings:用于保存简短的文本属性,字符串个数限制为255,8个字节
    Long strings:用于保存二进制数据块。
    Field tables:包含键值对,字段值一般为字符串,整数等。

上一篇:RabbitMQ(十二)——springboot整合RabbitMQ


下一篇:RabbitMQ入门