乐趣区

关于java:常见消息中间件大-PK

@[toc]
说到消息中间件,预计大伙多多少少都能讲进去一些,ActiveMQ、RabbitMQ、RocketMQ、Kafka 等等各种以及 JMS、AMQP 等各种协定,然而这些消息中间件各自都有什么特点,咱们在开发中又该抉择哪种呢?明天松哥就来和小伙伴们梳理一下。

1. 几种协定

先来说说消息中间件中常见的几个协定。

1.1 JMS

1.1.1 JMS 介绍

先来说说 JMS。

JMS 全称 Java Message Service,相似于 JDBC,不同于 JDBC,JMS 是 JavaEE 的音讯服务接口,JMS 次要有两个版本:

  • 1.1
  • 2.0。

两者相比,后者次要是简化了收发音讯的代码。

思考到消息中间件是一个十分罕用的工具,所以 JavaEE 为此制订了专门的标准 JMS。

不过和 JDBC 一样,JMS 作为标准,他只是一套接口,并不蕴含具体的实现,如果咱们要应用 JMS,那么个别还须要对应的实现,这就像应用 JDBC 须要对应的驱动一样。

1.1.2 JMS 模型

JMS 音讯服务反对两种音讯模型:

  • 点对点或队列模型
  • 公布 / 订阅模型

在点对点或队列模型下,一个生产者向一个特定的队列公布音讯,一个消费者从该队列中读取音讯。这里,生产者晓得消费者的队列,并间接将音讯发送到对应的队列。这是一种点对点的音讯模型,这种模式被概括为:

  1. 只有一个消费者将取得音讯。
  2. 生产者不须要在消费者生产该音讯期间处于运行状态,消费者也同样不须要在音讯发送时处于运行状态,即音讯的生产者和消费者是齐全解耦的。
  3. 每一个胜利解决的音讯都由音讯消费者签收。

发布者 / 订阅者模型反对向一个特定的音讯主题公布音讯,消费者则能够定义本人感兴趣的主题,这是一种点对面的音讯模型,这种模式能够被概括为:

  • 多个消费者能够生产音讯。
  • 在发布者和订阅者之间存在工夫依赖性,发布者须要创立一个订阅(subscription),以便客户可能订阅;订阅者必须放弃在线状态以接管音讯;当然,如果订阅者创立了长久的订阅,那么在订阅者未连贯时,音讯生产者公布的音讯将会在订阅者从新连贯时从新公布。

1.1.3 JMS 实现

开源的反对 JMS 的消息中间件有:

  • Kafka
  • Apache ActiveMQ
  • JBoss 社区的 HornetQ
  • Joram
  • Coridan 的 MantaRay
  • OpenJMS

一些商用的反对 JMS 的消息中间件有:

  • WebLogic Server JMS
  • EMS
  • GigaSpaces
  • iBus
  • IONA JMS
  • IQManager(2005 年 8 月被 Sun Microsystems 并购)
  • JMS+
  • Nirvana
  • SonicMQ
  • WebSphere MQ

这里有不少是松哥考古开掘进去的,其实对于咱们日常开发接触较多的,可能就是 Kafka 和 ActiveMQ。

1.2 AMQP

1.2.1 AMQP 简介

另一个和消息中间件无关的协定就是 AMQP 了。

Message Queue 的需要由来已久,80 年代最早在金融交易中,高盛等公司采纳 Teknekron 公司的产品,过后的 Message Queue 软件叫做:the information bus(TIB)。TIB 被电信和通信公司采纳,路透社收买了 Teknekron 公司。之后,IBM 开发了 MQSeries,微软开发了 Microsoft Message Queue(MSMQ)。这些商业 MQ 供应商的问题是厂商锁定,价格昂扬。2001 年,Java Message Service 试图解决锁定和交互性的问题,但对利用来说反而更加麻烦了。

于是 2004 年,摩根大通和 iMatrix 开始着手 Advanced Message Queuing Protocol(AMQP)凋谢规范的开发。2006 年,AMQP 标准公布。2007 年,Rabbit 技术公司基于 AMQP 规范开发的 RabbitMQ 1.0 公布。

目前 RabbitMQ 的最新版本为 3.5.7,基于 AMQP 0-9-1。

在 AMQP 协定中,音讯收发波及到如下一些概念:

  • Broker: 接管和散发音讯的利用,咱们日常所用的 RabbitMQ 就是一个 Message Broker。
  • Virtual host: 出于多租户和平安因素设计的,把 AMQP 的根本组件划分到一个虚构的分组中,相似于网络中的 namespace 概念。当多个不同的用户应用同一个 RabbitMQ 提供的服务时,能够划分出多个 vhost,每个用户在本人的 vhost 中创立 exchange/queue 等,这个松哥之前写过专门的文章,传送门:[RabbitMQ 中的 VirtualHost 该如何了解]()。
  • Connection: publisher/consumer 和 broker 之间的 TCP 连贯,断开连接的操作只会在 client 端进行,Broker 不会断开连接,除非呈现网络故障或 broker 服务呈现问题。
  • Channel: 如果每一次拜访 RabbitMQ 都建设一个 Connection,在音讯量大的时候建设 TCP Connection 的开销将是微小的,效率也较低。Channel 是在 Connection 外部建设的逻辑连贯,如果应用程序反对多线程,通常每个 Thread 创立独自的 Channel 进行通信,AMQP method 蕴含了 Channel id 帮忙客户端和 Message Broker 辨认 Channel,所以 Channel 之间是齐全隔离的。Channel 作为轻量级的 Connection 极大缩小了操作系统建设 TCP Connection 的开销,对于 Channel,松哥在 RabbitMQ 治理页面该如何应用一文中也做过具体介绍。
  • Exchange: Message 达到 Broker 的第一站,依据散发规定,匹配查问表中的 routing key,散发音讯到 queue 中去。罕用的类型有:direct (点对点), topic(公布订阅) 以及 fanout (播送)。
  • Queue: 音讯最终被送到这里期待 Consumer 取走,一个 Message 能够被同时拷贝到多个 queue 中。
  • Binding: Exchange 和 Queue 之间的虚构连贯,binding 中能够蕴含 routing key,Binding 信息被保留到 Exchange 中的查问表中,作为 Message 的散发根据。

1.2.2 AMQP 实现

来看看实现了 AMQP 协定的一些具体的消息中间件产品都有哪些。

  • Apache Qpid
  • Apache ActiveMQ
  • RabbitMQ

可能有小伙伴奇怪咋还有 ActiveMQ?其实 ActiveMQ 不仅反对 JMS,也反对 AMQP,这个松哥前面细说。

另外还有大家熟知的阿里出品的 RocketMQ,这个是自定义了一套协定,社区也提供了 JMS,然而不太成熟,前面松哥细说。

1.3 MQTT

做物联网开发的小伙伴应该会常常接触这个协定,MQTT(Message Queuing Telemetry Transport,音讯队列遥测传输)是 IBM 开发的一个即时通讯协定,目前看来算是物联网开发中比拟重要的协定之一了,该协定反对所有平台,简直能够把所有联网物品和内部连接起来,被用来当做传感器和 Actuator(比方通过 Twitter 让屋宇联网)的通信协议,它的长处是格局简洁、占用带宽小、反对挪动端通信、反对 PUSH、实用于嵌入式零碎。

1.4 XMPP

XMPP(可扩大音讯解决现场协定,Extensible Messaging and Presence Protocol)是一个基于 XML 的协定,多用于即时消息(IM)以及在线现场探测,实用于服务器之间的准即时操作。外围是基于 XML 流传输,这个协定可能最终容许因特网用户向因特网上的其余任何人发送即时消息,即便其操作系统和浏览器不同。它的长处是通用公开、兼容性强、可扩大、安全性高,毛病是 XML 编码格局占用带宽大。

1.5 JMS Vs AMQP

对于咱们 Java 工程师而言,大家日常接触较多的应该是 JMS 和 AMQP 协定,既然 JMS 和 AMQP 都是协定,那么两者有什么区别呢?来看上面一张图:

这张图说的很分明了,我就不啰嗦了。

2. 重要产品

2.1 ActiveMQ

ActiveMQ 是 Apache 下的一个子项目,应用齐全反对 JMS1.1 和 J2EE1.4 标准的 JMS Provider 实现,大量代码就能够高效地实现高级利用场景,并且反对可插拔的传输协定,如:in-VM, TCP, SSL, NIO, UDP, multicast, JGroups and JXTA transports

ActiveMQ 反对罕用的多种语言客户端如 C++、Java、.Net,、Python、Php、Ruby 等。

当初的 ActiveMQ 分为两个版本:

  • ActiveMQ Classic
  • ActiveMQ Artemis

这里的 ActiveMQ Classic 就是原来的 ActiveMQ,而 ActiveMQ Artemis 是在 RedHat 捐献的 HornetQ 服务器代码的根底上开发的,两者代码齐全不同,后者反对 JMS2.0,应用基于 Netty 的异步 IO,大大晋升了性能,更为神奇的是,后者不仅反对 JMS 协定,还反对 AMQP 协定、STOMP 以及 MQTT,能够说后者的玩法相当丰盛。

因而大家在应用时,倡议间接抉择 ActiveMQ Artemis。

2.2 RabbitMQ

RabbitMQ 算是 AMQP 体系下最为重要的产品了,它基于 Erlang 语言开发实现,预计很多人被 RabbitMQ 的装置折磨过,松哥倡议装置 RabbitMQ 间接用 Docker,省心省力(公号后盾回复 docker 有教程)。

RabbitMQ 反对 AMQP、XMPP、SMTP、STOMP 等多种协定,功能强大,实用于企业级开发。

来看一张 RabbitMQ 的结构图:

对于 RabbitMQ,松哥最近发了十来篇教程了,这里就不再啰嗦了。

2.3 RocketMQ

RocketMQ 是阿里开源的一款分布式消息中间件,原名 Metaq,从 3.0 版本开始改名为 RocketMQ,是阿里参照 Kafka 设计思维应用 Java 语言实现的一套 MQ。RocketMQ 将阿里外部多款 MQ 产品(Notify、Metaq)进行整合,只保护外围性能,去除了所有其余运行时依赖,保障外围性能最简化,在此基础上配合阿里上述其余开源产品实现不同场景下 MQ 的架构,目前次要用于订单交易系统。

RocketMQ 具备以下特点:

  • 保障严格的音讯程序。
  • 提供针对音讯的过滤性能。
  • 提供丰盛的音讯拉取模式。
  • 高效的订阅者程度扩大能力。
  • 实时的音讯订阅机制。
  • 亿级音讯沉积能力

对于 Java 工程师而言,这也是一种常常会用到的 MQ。

2.4 Kafka

Kafka 是 Apache 下的一个开源流解决平台,由 Scala 和 Java 编写。Kafka 是一种高吞吐量的分布式公布订阅音讯零碎,它能够解决消费者在网站中的所有动作(网页浏览,搜寻和其余用户的口头)流数据。Kafka 的目标是通过 Hadoop 的并行加载机制来对立线上和离线的音讯解决,也是为了通过集群来提供实时的音讯。

Kafka 具备以下个性:

  • 疾速长久化:通过磁盘程序读写与零拷贝机制,能够在 O(1) 的零碎开销下进行音讯长久化。
  • 高吞吐:在一台一般的服务器上既能够达到 10W/s 的吞吐速率。
  • 高沉积:反对 topic 下消费者较长时间离线,音讯沉积量大。
  • 齐全的分布式系统:Broker、Producer、Consumer 都原生主动反对分布式,通过 Zookeeper 能够主动实现更加简单的负载平衡。
  • 反对 Hadoop 数据并行加载。

大数据开发中大家可能会常常接触 Kafka,Java 开发中也会接触,然而相对来说可能接触的少一些。

2.5 ZeroMQ

ZeroMQ 号称最快的音讯队列零碎,它专门为高吞吐量 / 低提早的场景开发,在金融界的利用中常常应用,偏重于实时数据通信场景。ZeroMQ 不是独自的服务,而是一个嵌入式库,它封装了网络通信、音讯队列、线程调度等性能,向下层提供简洁的 API,应用程序通过加载库文件,调用 API 函数来实现高性能网络通信。

ZeroMQ 的个性:

  • 无锁的队列模型:对于跨线程间的交互(用户端和 session)之间的数据交换通道 pipe,采纳无锁的队列算法 CAS,在 pipe 的两端注册有异步事件,在读或者写音讯到 pipe 时,会主动触发读写事件。
  • 批量解决的算法:对于批量的音讯,进行了适应性的优化,能够批量的接管和发送音讯。
  • 多核下的线程绑定,毋庸 CPU 切换:区别于传统的多线程并发模式,信号量或者临界区,ZeroMQ 充分利用多核的劣势,每个核绑定运行一个工作者线程,防止多线程之间的 CPU 切换开销。

2.6 其余

另外还有如 Redis 也能做音讯队列,松哥之前也发过文章和大家介绍用 Redis 做一般音讯队列和提早音讯队列,这里也就不啰嗦了。

3. 比拟

最初,咱们再来通过一张图来比拟下各个消息中间件。

小伙伴们在公众号后盾回复 mqpkmq,能够获取这个 Excel 表格链接。

好啦,就扯这么多。

退出移动版