文章目录
  1. 1.概述
    1. 1.1 概念
    2. 1.2 JMS规范
      1. 1.2.1 点对点模型(P2P, 消息不分类)
      2. 1.2.2 发布订阅模型(消息按主题分类)
    3. 1.3 消息的优点
    4. 1.4 开源中间件
      1. 1.4.1 Apache ActiveMQ
      2. 1.4.2 Apache Kafka
      3. 1.4.3 Apache RocketMQ
      4. 1.4.4 Pivotal RabbitMQ
  2. 4.消息集群(主从架构)
    1. 4.1 架构
    2. 4.2 扩展

消息中间件是大型分布式应用中重要的组成部分,它可以实现关联系统在业务和部署上的解耦,各方无需相互等待,只需根据自身能力投递或消费。本文总结了JMS各元素、两种消息模型、主流的消息中间件 (Kafka/ActiveMQ/RabbitMQ/RocketMQ)各自的特点。

作者:王克锋
出处:https://kefeng.wang/2017/10/12/message-queue/
版权:自由转载-非商用-非衍生-保持署名,转载请标明作者和出处。

1.概述

https://zh.wikipedia.org/zh-cn/Java消息服务

1.1 概念

分布式系统中发送和接受消息的硬件或软件基础设施(通常是指软件),分布式消息中间件自身也是一个分布式系统。
不同于 RMI/RPC 等通信机制,消息队列(Message Queue)是应用间异步通信的机制。
流程: 消息生产者(producer) ==(异步)==> 消息队列(message queue, broker) ==> 消息消费者(consumer)
其中的 producer/consumer 都可以有多个,他们都不受限于特定平台。

消息的类型:

  • 简单文本(TextMessage)、字节流(ByteMessage)、键值对(MapMessage)
  • 流(StreamMessage)、可序列化的对象(ObjectMessage)、原始(Message)

1.2 JMS规范

Java消息服务(Java Message Service, JMS)是一个在 Java标准化组织(JCP)内开发的标准(代号JSR 914)。
2001年6月25日,发布 JMS 1.0.2b,
2002年3月18日,发布 JMS 1.1,统一了消息域。

JDBC 是 Java 数据库的统一接口规范;
类似地,JMS()是 Java 异步消息应该接口规范,它包括消息的创建、发送、接收与读取等,各消息组件厂商必须遵从该规范。

JMS元素包括:

  • JMS提供者: 连接面向消息中间件的,JMS接口的一个实现。提供者可以是Java平台的JMS实现,也可以是非Java平台的面向消息中间件的适配器。
  • JMS客户: 生产或消费消息的基于Java的应用程序或对象。
  • JMS生产者: 创建并发送消息的JMS客户。
  • JMS消费者: 接收消息的JMS客户。
  • JMS消息: 包括可以在JMS客户之间传递的数据的对象
  • JMS队列: 一个容纳那些被发送的等待阅读的消息的区域。队列暗示,这些消息将按照顺序发送。一旦一个消息被阅读,该消息将被从队列中移走。
  • JMS主题: 一种支持发送消息给多个订阅者的机制。

1.2.1 点对点模型(P2P, 消息不分类)

  • 发送时: producer 发送 {message} 给 broker,broker 把 message 放到队列中
  • 接收时: 一旦有 consumer 接收消息,consumer 从队列中移出最早的 message,转交给该 consumer;其他 consumer 就不会收到同一个 message。

1.2.2 发布订阅模型(消息按主题分类)

  • 接收者: 向 broker 订阅某些 topic;
  • 发送时: producer 发送 message 给 broker 的某个 topic,broker 把 message 放到相应 topic 的队列中;
  • 接收时: broker 把该 message 群发给订阅了该 topic 的所有在线的 consumer;已订阅该 topic 但已下线的 consumer,再次上线也不会收到该 message,除非该 consumer 开启了“持久订阅(Durable Subscription)”;后来才首次订阅该 topic 的 consumer,也不会收到该 message。

1.3 消息的优点

  • 无需等待: producer 无需等待消息被投递,更无需等待消息被 consumer 接收和处理;
  • 业务解耦: 以消息为中心,与外围系统在衔接接口上解耦;
  • 位置独立: 以消息为中心,与外围系统在网络拓扑上解耦,可以很方便地增加 producer/consumer;
  • 确保投递: 确保每个消息都会投递给 consumer,即使 consumer 暂时宕机,在恢复之后仍能收到遗漏的消息。
  • 削峰填谷: 当 consumer 来不及处理时,缓存在消息系统中,待 consumer 高峰期过后再继续处理。

1.4 开源中间件

性能: Kafka > RocketMQ > RabbitMQ
架构: ActiveMQ / RabbitMQ 只支持主从模式,Kafka / RocketMQ 支持分布式;
持久化: ZeroMQ 不支持,ActiveMQ / RabbitMQ 都支持。
可靠性: RabbitMQ > ActiveMQ

1.4.1 Apache ActiveMQ

最新版本 5.15.2(2017-10-23)
可以部署于代理模式和P2P模式。
被誉为消息中间件的“瑞士军刀”。

1.4.2 Apache Kafka

由 LinkedIn 开发贡献给 Apache,主要特性:

  • 不完全符合 JMS 规范,注重吞吐量(基于 Pull 的模式来处理消息消费),类似 TCP/UDP;
  • 支持复制,不支持事务
  • 对消息的重复、丢失、错误没有严格要求
  • kafka 对数据不是百分之百保证的,会有数据丢失;而amq和rmq等通过设置有查询是否送达、可重发;
  • 在吞吐量有提升 ,在这方面就得有牺牲, 所以kafka适合大数据量流转, 比如日志数据 比如用作统计的数据。
    Kafka Broker 使用 Zookeeper 在群集中可靠地维护自己的状态。

1.4.3 Apache RocketMQ

由 Alibaba 开源并贡献给 Apache,纯Java开发。

  • 思路源于 Kafka,具有高吞吐量、高可用性;
  • 它对消息的可靠传输及事务性做了优化。
  • 能够保证严格的消息顺序
  • 提供丰富的消息拉取模式
  • 高效的订阅者水平扩展能力
  • 实时的消息订阅机制
  • 亿级消息堆积能力

1.4.4 Pivotal RabbitMQ

Rabbit 公司采用 erlang 语言、基于 AMQP 协议开发。
Rabbit 公司 2010年4月被 VMware 旗下的 SpringSource 收购。
RabbitMQ 在 2013年5月成为 GoPivotal 的一部分。

主要特性:

  • 面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。
  • 对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。
  • 可群集服务、消息持久化(内存持久化到硬盘,再从硬盘加载到内存)

4.消息集群(主从架构)

4.1 架构

全局排他锁可以存储于共享文件系统,或者共享数据库中;
各节点启动时,竞相获取排他锁,首先获得者为 Master,其他为 Slave(不对外提供服务,并尝试获取排他锁);
当 Master 宕机或连接中断时,排他锁被释放,并被某个 Slave 抢得而成为 Master 并对外提供服务;
而先前的 Master 再次恢复后,也只能作为 Slave 等待争夺排他锁。
客户端连接集群时,要同时指定所有节点。

4.2 扩展

  • 垂直扩展: 提升硬件性能(CPU、内存等),改进 broker 节点的配置(NIO、JVM等);
  • 水平扩展: 增加 broker,拆分存储不同的消息、主题。
文章目录
  1. 1.概述
    1. 1.1 概念
    2. 1.2 JMS规范
      1. 1.2.1 点对点模型(P2P, 消息不分类)
      2. 1.2.2 发布订阅模型(消息按主题分类)
    3. 1.3 消息的优点
    4. 1.4 开源中间件
      1. 1.4.1 Apache ActiveMQ
      2. 1.4.2 Apache Kafka
      3. 1.4.3 Apache RocketMQ
      4. 1.4.4 Pivotal RabbitMQ
  2. 4.消息集群(主从架构)
    1. 4.1 架构
    2. 4.2 扩展