# 简介

# 消息队列

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

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

# JMS

JMS(Java Message Service ,Java 消息服务):Java 平台上消息中间件的 API 规范。

基本概念:

  • 客户端 :连接到 MQ 服务器的程序,可以作为消息的发送方(Sender)或接收方(Receiver)。
  • 消息 :程序之间的通信内容。

JMS 定义了两种传输消息的模式:

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

# 常见的消息队列

  • ActiveMQ

  • RabbitMQ

    • 采用 erlang 开发,实现了高级消息队列(Advanced Message Queuing Protocol ,AMQP)协议。
    • 并发能力强,延迟很低。
    • 生产者发送的消息,会由 exchange(交换机)转发到某个或某些队列。
  • RocketMQ

    • 采用 Java 开发,由阿里巴巴公司开源,捐献给了 ASF 。
    • 它借鉴了 Kafka ,但功能更强。
  • Kafka