# 消息中间件

## 基本概念

**消息队列** Message Queue: 消息队列是一种在分布式和大数据开发中不可或缺的中间件. 在分布式开发或者大数据开发中通常使用消息队列进行缓存, 系统间解耦和削封填谷等业务场景, 常见的消息队列的工作模式大致会分为为两大类:

* 至多一次: 消息生产者将消息写入到MQ, 消费者负责去MQ中拉取消息, 一旦消息被确认消费, 由消息服务器主动删除队列中的数据, 这种消费模式一般只允许被一个消费者消费,并且不能被重复消费
* 没有限制: 生产者发布完新消息后, 消息可以被多个消费者消费, 并且同一个消费者可以多次消费消息服务器中的同一记录. 主要是因为消息服务器可以存储海量信息.

![image-20210117210758904](https://2351062869-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7b2CdwBN9liniVJpfEAc%2Fuploads%2Fgit-blob-339dfa89e600206dbd8d9de48fd420387b443598%2Fimage-20210117210758904.png?alt=media)

## 应用场景

### 异步通讯, 减少接口耗时

`用户发起请求-执行注册服务-执行发送短信服务-响应用户` 串联调用导致客户等待响应时间较长. 如果使用消息队列, 将会向MQ中新增一条消息, 然后直接响应给客户. 增快了接口的响应速度.减少了资源消耗.

![file](https://2351062869-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7b2CdwBN9liniVJpfEAc%2Fuploads%2Fgit-blob-c1d3c05bc9ca01d15e5c5389cf6d7d4a73f828d2%2Fimage-1612061482405.png?alt=media)

### 系统解耦

如果短信业务出现故障, 将直接反映在用户注册服务上. 如果使用MQ, 即使短信服务不可用, 不会影响用户的注册, 最多会延迟受到短信.

### 削峰填谷

![file](https://2351062869-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7b2CdwBN9liniVJpfEAc%2Fuploads%2Fgit-blob-f3a09c16334f595b1442d46d0fae3cc68f5a35fb%2Fimage-1612061638240-1612061776884.png?alt=media)

日志产生的流量是不确定的, 高峰期时候会很高, 低谷时期会很低, 当日志很多时, 高流量可能会让流计算无法适应处理, 为了保护流计算, 通过增加中间件MQ缓冲日志流量. 于此类似, 流计算后方的MQ同样也是为了保护数据执行而存在的.

## 常见的MQ产品

### ActiveMQ

Java语言开发的，在较早的时候，很多项目都采用这种MQ。现在社区活跃度很低，很少有人使用了。

### RabbitMQ

Erlang开发的一款MQ产品。其吞吐量比Kafka与RocketMQ都要低，并且因为语言的特殊性，很难做定制化的开发，但是相对来说使用的较为广泛。

### Kafka

Kafka是Apache开发的一款开源 **流处理平台**(网络信息流,日志流, 采样流), 由Scala和Java编写. Kafka是一种 **高吞吐量的分布式发布订阅消息系统**, 一般用作系统间解耦, 异步通讯, 削峰填谷等作用. 此外还提供了流处理插件 Kaka Streaming(类似Storm, Spark, Flink), 并且运行在应用端. 具有简单 , 入门要求低, 部署方便等优点.

> Kafka没有遵循任何常见的MQ协议，而是使用自研协议。

### RocketMQ

RocketMQ是使用Java语言开发的MQ产品，经过阿里巴巴十几年的考验，性能与稳定性非常高。

> RocketMQ没有遵循任何常见的MQ协议，而是使用自研协议。

### 产品对比

| 参数    | ActiveMQ | RabbitMQ        | Kafka            | RocketMQ |
| ----- | -------- | --------------- | ---------------- | -------- |
| 开发语言  | Java     | ErLang          | Java             | Java     |
| 单机吞吐量 | 万级       | 万级              | 十万级              | 十万级      |
| Topic |          | 百Topic时会影响系统吞吐量 | 千级Topic时会影响系统吞吐量 |          |
| 社区活跃度 | 低        | 高               | 高                | 高        |

## 常见的MQ协议

### JMS

Java Messaging Service，Java消息服务。是Java平台上关于MOM（Message Oriented Middleware 面向消息中间件）的技术规范，便于消息系统中的Java应用程序进行消息交换，并且通过提供标准的产生、推送、接收消息的接口，简化企业应用开发。ActiveMQ是该协议的典型实现。

### STOMP

Streaming Text Oriented Message Protocol，是一种MOM设计的简单文本协议。提供一个可互操作的连接格式，允许客户端与任意的STOMP消息代理（Broker）进行交互。ActiveMQ是该协议的典型实现，RabbitMQ可通过插件实现该协议。

### AMQP

Advanced Message Queuing Protocol，是一个提供统一消息服务的应用层标准，是应用层协议的一个开放标准，是一种MOM设计。基于此协议的客户端与中间件可互相传递消息，不受语言、客户端、消息中间件的限制。RabbitMQ是典型实现。

### MQTT

Message Queue Telemetry Transport，是IBM开发的一个即使通讯程序，是一种二进制协议，主要用于服务器和低功耗IoT设备间的通讯。协议支持所有平台，几乎可以把所有物联网和外部连接起来，被用来做传感器和致动器的通讯协议。RabbitMQ可以通过插件支持该协议。
