# 简介

# MQ

MQ(Message Queue ,消息队列):一种用于程序之间通信的中间件,可以暂存消息。先由发送方将消息放入消息队列,再由接收方从中获取消息。

  • 优点:
    • 解耦 :每个程序只需要考虑对 MQ 的访问,不必直接与其它程序通信,因此耦合度低。
    • 异步 :消息的发送方和接收方异步工作,避免了等待对方回复的时间。
    • 削峰 :即使发送方突然发出了大量消息,接收方也依然是按照自己的速度从 MQ 获取消息,因此可以削弱消息数量的峰值。
  • 缺点:
    • 增加了系统的复杂度,需要多考虑一个中间件。
    • 当消费者速度滞后时,不能实时处理消息。滞后量越大,每个消息从生产到消费的耗时越久。
  • 难点:
    • 如何保证消息不被重复消费。
      • 可以给每个消息分配一个唯一 ID ,客户端记录自己获得的所有消息 ID ,如果收到重复的消息就忽略。或者服务器记录每个客户端获得的所有消息 ID ,不发送重复的消息。
    • 如何保证不丢失消息。
      • 可能原因:客户端发布或接收消息时丢失、消息队列存储消息时丢失。
    • 性能是否足以处理高并发请求、海量消息。

# MQ 协议

# JMS

JMS(Java Message Service ,Java 消息服务):一个 API 规范,描述了 Java 程序如何调用消息中间件。

  • 于 1998 年发布。

  • JMS 是仅适用 Java 语言的 API 规范。不过很多 MQ 软件提供了符合 JMS 规范的 MQ 协议,或者借鉴了 JMS 规范。

  • 基本概念:

    • 消息:程序之间的通信内容。
    • 客户端:连接到 MQ 服务器的程序。还可细分为消息的发送方(Sender)、接收方(Receiver)。
  • JMS 定义了两种传输消息的模式:

    • 点对点模式(Point to Point ,P2P)
      • 一条消息只能被一个客户端接收。
      • 消息的发送方、接收方分别称为生产者(Producer)、消费者(Consumer)。
      • Producer 将消息发送到某个队列(Queue)中,而消费者到某个 Queue 中获取消息(该过程称为消费)。
      • 队列会长时间保存消息,直到它被消费或超时。
    • 发布/订阅模式(Publish/Subscribe)
      • 一条消息可以被多个客户端接收。
      • 消息的发送方、接收方分别称为发布者(Publisher)、订阅者(Subscriber)。
      • Publisher 将消息发布到某个主题(Topic)下,而 MQ 会立即将该消息推送给订阅该 Topic 的所有 Subscriber 。
      • 一个 Subscriber 可以订阅任意个 Topic ,但是只会收到订阅之后新发布的消息,不会收到历史消息,因为 MQ 不会长时间保存消息。

# AMQP

AMQP(Advanced Message Queuing Protocol ,高级消息队列协议)

  • 于 2003 年发布。最初由摩根大通主导,用于解决金融公司之间的消息传递问题。
  • 属于应用层协议,基于 TCP 通信。
  • 与 JMS 相比,AMQP 是一个通用的 MQ 协议,跨语言。

# MQTT

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输):一个主要用于物联网通信的 MQ 协议。

  • 于 1999 年发布。
  • 属于应用层协议,基于 TCP 通信。
  • 适用于低带宽、不可靠网络中的通信。
  • 采用 C/S 架构。
    • mqtt server 又称为 mqtt broker 。常见的服务器软件有 ActiveMQ、mosquitto、EMQ 等。
    • mqtt client 与 mqtt broker 建立连接之后就构成了一个会话(Session)。
  • 采用发布/订阅模式(Publish/Subscribe)。
    • client 可以发布消息到 mqtt broker 的某个 topic 下,此时称为 Publisher 。
    • client 也可以订阅 mqtt broker 的某个 topic 下的消息,此时称为 Subscriber 。

# MQ 软件

  • ActiveMQ

    • 是第一个实现 JMS 规范的开源 MQ 软件,后来也支持 AMQP、STOMP、MQTT 等协议。
    • 于 2004 年发布,采用 Java 语言开发。后来该项目交给 ASF 基金会管理。
  • RabbitMQ

    • 是第一个实现 AMQP 协议的开源 MQ 软件,后来也支持 JMS、STOMP、MQTT 等协议。
    • 于 2007 年发布,采用 erlang 语言开发。后来该项目被 VMWare 公司收购。
    • 默认监听 TCP 5672 端口。
    • 并发能力强,延迟很低。
  • Kafka

    • 2011 年由 LinkedIn 公司开源,后来交给 ASF 基金会管理。
      • 主要开发者离职后创建了 Confluent 公司,提供功能更多的 Kafka 发行版,分为开源版、企业版。
    • 采用 Scala 语言开发。
    • 吞吐量比 ActiveMQ、RabbitMQ 高了一个数量级,因此更适合处理大数据。
  • RocketMQ

    • 2012 年由阿里巴巴公司开源,后来交给 ASF 基金会管理。
    • 采用 Java 语言开发,借鉴了 Kafka、RabbitMQ 。