本文探讨了JMS消息传递中间件和Kafka部署的差异、权衡和体系结构。比较基于JMS的消息队列(MQ)基础设施和基于ApacheKafka的数据流是一个广泛的话题。本文探讨了JMS消息代理和Kafka部署的差异、权衡和架构,并分析了如何在JMS代理(例如IBMMQ或RabbitMQ)和开源Kafka或无服务器云服务(例如Confluent)之间进行选择云)。动机:苹果和橘子之战KaiWaehner在Confluent担任技术布道者。经常在JavaOne、O'ReillySoftwareArchitecture或ApacheCon等国际会议上发表演讲,为专业期刊撰写文章,分享新技术经验。Kai几乎每周都需要在客户会议上讨论JMS消息代理和ApacheKafka之间的差异和权衡。他发现对JMS、Kafka有很多误解,偶尔看到一些不合适的博文和演讲,这让他很恼火,整理了十个比较标准,目的是解释消息队列和数据的区别streams,澄清对相关API或实现部署的一些常见误解,并提供相应的技术选型注意事项。10比较标准:JMS和ApacheKafkaJMS和Kafka都提供了一系列产品和云服务,例如:JMSAPI实现(包括开源和商业产品):ApacheActiveMQ、ApacheQpid(使用AMQP)、IBMMQ(以前MQSeries,现在是WebSphereMQ)、JBossHornetQ、OracleAQ、RabbitMQ、TIBCOEMS、TIBCOCloudMessaging、Solace等。ApacheKafka产品、云服务和重写(不仅使用开源Kafka的有效选项):Confluent、Cloudera、AmazonMSK、RedHat、Redpanda、AzureEventHubs等。以下是JMS消息代理与ApacheKafka及其相关产品/云服务的比较标准:1.消息代理和数据流平台2.API规范和开源协议实现3.事务处理和负载分析4.推拉消息5.simplified,powerfulandcomplexAPI6.持久化存储和真正解耦7.服务器端数据处理和解耦连续数据流处理8.复杂操作和无服务器云9.Java/JVM和任何编程语言10.单一部署和多区域(包括混合和多云)复制现在探索这十个比较标准中的每一个。1、JMS和Kafka有很大的区别。JMS消息代理提供消息发送和接收功能,包括生成和使用消息。ApacheKafka是一个集消息传递、存储、数据集成和流处理于一体的数据流平台。首先,在Kai看来,JMS和ApacheKafka的区别是相当巨大的,甚至可以说两者不是一回事。JMSAPI(以及IBMMQ、RabbitMQ等的实现)JMS(Java消息服务)是一种提供通用消息传递模型的Java应用程序编程接口(API)。API处理生产者-消费者问题,以方便软件系统之间消息的发送和接收。因此,JMS消息代理(并实现JMSAPI)的核心功能是将消息从源应用程序实时发送到另一个目的地。所以需要根据实际使用需求来选择JMS!值得注意的一件事是,项目必须使用额外的工具来进行数据集成和高级数据处理任务。ApacheKafka(开源和供应商,如Confluent、Cloudera、RedHat、Amazon等)ApacheKafka是一种用于数据流的开源协议实现。这包括:ApacheKafka是分布式消息传递和存储的核心,可实现高吞吐量、低延迟、高可用性和安全性。KafkaConnect是一个集成框架,用于将外部源/目标连接到Kafka。KafkaStreams是一个简单的Java库,支持在Kafka框架内开发流式应用程序。这种功能组合可以构建端到端的数据管道和应用程序,因此Kafka组合的使用范围比消息队列更广泛。2.API规范和开源协议实现JMS是厂商以自己的方式实现和扩展的规范。ApacheKafka是底层指定Kafka协议的开源实现。在评估和比较JMS和Kafka之前,更重要的是澄清以下术语:标准API:标准API由行业联盟或其他行业中立的(通常是全球性的)机构或组织指定。所有功能都需要进行合规性测试和认证才能符合该标准。示例:OPC-UA标准事实上的标准API:源自现有的成功解决方案(开源框架、商业产品或云服务)。示例:AmazonS3(来自单一供应商的所有权)、ApacheKafka(来自充满活力的社区的开源)。API规范:定义供应商如何实现相关产品的规范文档。没有针对所有功能实施的完整合规性测试或完整认证。结果是实现之间没有可移植性的“标准API”。例如:JMS,请注意,为了能够使用JMS的合规性组件集,供应商必须向Oracle签署非常繁重的报告。替代类型的标准需要权衡取舍。如果您想了解更多信息,请查看ApacheKafka在过去几年中如何成为数据流的事实标准。可移植性和迁移在混合云和多云环境中比在过去几十年将工作负载放置在单个数据中心时更为重要。JMS是面向消息的中间件的规范JMS是目前在JavaCommunityProcess下作为JSR343维护的规范。最新(尚未发布)版本JMS3.0作为JakartaEE的一部分处于早期开发阶段,已更名为Jakarta消息传递API。今天,JMS2.0是流行的消息代理实现中使用的规范(没有人知道JMS3.0将走向何方)。因此,此处的重点是JMS2.0规范以应对现实世界的挑战。通常,当人们提到JMS时,他们指的是JMS消息代理实现,而不是JMSAPI规范。下面将使用“JMSmessagebroker”来代替JMS(即API),并没有具体说明JMS实现的已知特性。JMS消息代理和JMS可移植性神话JMS开发规范提供了一个公共Java库来访问来自不同消息提供者的代理。它用作消息代理供应商专有API的包装器,就像JDBC为数据库API提供类似的功能一样。然而,这个简单的积分结果并没有实现。因为将JMS代码从一个提供者的代理迁移到另一个提供者的代理很复杂,原因如下:并非所有JMS功能都是必需的(安全性、队列标记、集群、路由、压缩等)JMS规范没有定义如何实现持久性的规范.没有规范来定义如何实现容错或高可用性。不同供应商对JMS规范的不同解释可能导致同一JMS功能的行为存在潜在差异。规范(例如主题到队列桥接、代理间路由、访问控制列表等)因此,JMS供应商之间轻松的源代码迁移和互操作性是一个神话!供应商在代理中提供了大量独特的功能(例如:主题到队列的映射、代理路由等),这些功能为应用程序提供架构功能,但它们是代理功能的一部分,而不是应用程序或JMS规范的一部分。ApacheKafka是数据流的开源协议实现ApacheKafka是实时数据流处理的可靠且可扩展的实现。该项目是开源的,在Apache2.0许可下可用,并由大型社区驱动。ApacheKafka不是像OPC-UA这样的标准,也不是像JMS这样的规范。但是,Kafka至少提供了源代码、参考实现、协议和API定义等,Kafka已经成为数据流领域的事实标准。如今,超过100,000个组织使用ApacheKafka;KafkaAPI也已成为事件驱动架构和事件流的事实标准。它在所有行业和基础设施中都有用例,包括边缘、混合和多云环境中的各种事务处理和分析工作负载。有些人可能不熟悉KafkaAPI。在此澄清一下:前面提到,ApacheKafka是一个分布式数据流平台的实现,包括服务端和客户端以及生产和消费事件、配置、安全、操作等各种API。KafkaAPI也是很重要,因为Kafka可以被重写,例如AzureEventHubs和Redpanda使用它们。ApacheKafka可移植性:另一个神话?ApacheKafka作为一个开源项目,本身已经是一个非常完善的Kafka实现。一些供应商已经采用了整个ApacheKafka解决方案并围绕它构建了更高级的产品。Kafka的迁移非常简单,因为对于Kafka来说,不同的供应商采用相同的规范,代码、库、包都是一样的。例如,从Cloudera到Confluent部署的迁移,或者从自我管理的ApacheKafka开源基础设施到无服务器ConfluentCloud的迁移都非常成功。KafkaAPI:Kafka的重写,如AzureEventHubs、Redpanda、ApachePulsar随着Kafka在全球的成功,一些供应商和云服务并没有在ApacheKafka实现上构建产品。相反,他们使用KafkaAPI重建了他们的产品。底层实现要么是专有的(例如Azure的云服务事件中心),要么是开源的(例如ApachePulsar的Kafka桥或Redpanda用C++重写)。所以,我们要看供应商是否集成了整个ApacheKafka项目,或者是否重写了完整的API。使用KafkaAPI重写Kafka是一个全新的实现!许多供应商甚至在他们的支持条款和条件中完全排除某些组件或API(例如用于数据集成的KafkaConnect或用于流处理的KafkaStreams),或者排除诸如一次性语义或长期存储之类的东西。主要特征。市场上有各种各样的Kafka产品,例如:Kafka提供商,如Confluent、Cloudera、RedHat或AmazonMSK,以及相关技术,如AzureEventHubs、AWSKinesis、Redpanda或ApachePulsar。如何评价这些?首先,要求应该经过专业测试。如果Kafka-to-XYZbridge的代码不到一百行,或者是从中间件供应商那里下载的exe的WindowsKafkaserver程序,你肯定会对上面的代码和程序持怀疑态度。发光的不是金子。一些框架或供应商仍然有华而不实的嫌疑。比如只支持KafkaAPI,提供完全托管的serverlessKafka产品,在Kafka上推送不确定和可疑的功能(FUD)等。比如Kai就很恼火Pulsar总是想通过创造很多东西来比Kafka更好开源社区中的“不确定性和神话”。在凯看来,“不确定性”是供应商的错误策略。正因如此,Kafka的使用量还在疯狂增长,而Pulsar的百分比增长则要慢得多(当然,两者在下载量上的差距也非常明显)。3.事务和分析工作负载JMS消息代理仅支持低容量消息的事务功能。ApacheKafka更强大,它支持低容量和高容量消息,并支持事务和分析工作负载。JMS:会话和两阶段提交(XA)事务大多数JMS消息代理都很好地支持事务性工作负载。事务处理会话支持单个事务系列。每个事务将一组生产者消息和一组消费者消息组合成一个原子工作单元。两阶段提交事务(XA事务)的工作范围有限。它们适合与其他系统集成,例如大型机CICS/DB2或Oracle数据库。但它很难操作,不能扩展到每秒几笔交易。应该注意的是,与会话事务不同,JMS2.0规范不强制支持XA事务。Kafka:Exactly-OnceSemanticsandTransactionalAPIKafka是一个分布式容错系统,具有内在的弹性(如果您正确部署和操作它)。您可以放心,不会出现停机和数据丢失,就像在您最喜欢的数据库、大型机或其他核心平台中一样安全。更好的是:Kafka的事务API,Exactly-OnceSemantics(EOS),从Kafka0.11开始可用。EOS使构建事务性工作负载变得更加容易,因为您不再需要处理重复项。Kafka通过事务API支持跨多个分区的原子写事务。这允许生产者将一批消息发送到多个分区。一个批次中的所有消息最终对任何消费者可见,或者对消费者不可见。Kafka事务的工作方式与JMS事务非常不同。但目标是相同的:每个消费者只接收一次生成的事件。可以在博客文章“使用ApacheKafka在数据流中进行分析和事务”中找到更多详细信息。4.推送消息与拉取消息消费JMS消息代理将消息推送到消费者应用程序。Kafka消费者拉取消息,为独立的消费者应用程序提供真正的解耦和背压处理。推送消息似乎是实时消息传递系统(如基于JMS的消息代理)的明显选择。然而,基于推送的消息传递在解耦和可伸缩性方面存在各种缺点。JMS希望代理提供背压并实现“预取”功能,但这不是强制性的。如果使用,代理将控制您无法控制的背压。使用Kafka,消费者可以控制背压。每个Kafka消费者实时、批量或仅按需使用事件——以特定消费者支持和处理数据流的方式。对于许多不灵活和缺乏弹性的环境来说,这是一个巨大的优势。因此,虽然JMS有某种背压,但如果队列已满,生产者将停止。在Kafka中,您可以控制消费者背压。无法使用JMS扩展生产者(因为JMS队列或主题中没有分区)。JMS消费者可以扩展,但会失去有保证的顺序。JMS消息代理中的保证排序仅适用于单个生产者、单个消费者和事务。5.两者的API复杂度不同。JMSAPI提供简单的操作来生成和使用消息。ApacheKafka有一个更细粒度的API,它带来了额外的功能和复杂性。JMS供应商在其规范下的实现中隐藏了所有很酷的特性。您只能获得5%(没有控件,供应商提供的功能)。您需要自己实现其余功能。相反,Kafka暴露了一切,大多数开发人员只需要5%。总之,请注意,构建JMS消息代理是为了将消息从数据源发送到一个或多个数据接收器。Kafka是一个数据流平台,提供更多功能、特性、事件模式和处理选项;并且在更大的平台规模上。考虑到这一点,两者的API非常不同并且具有不同的复杂性也就不足为奇了。如果您的用例只需要每秒从A向B发送几条消息,那么JMS是正确的选择并且使用简单!如果你需要任何规模的流数据中心,包括数据集成和数据处理,只有Kafka。异步请求-回复与动态数据JMS开发人员的初衷之一是使用Kafka中的请求-响应功能。请注意,此设计模式不同于消息系统中的RPC(远程过程调用),其中消息代理中的请求-回复是使用关联ID的异步通信。从生产者(例如移动应用程序)到消费者(例如数据库)的异步消息传递是一种非常传统的工作流程。无论是执行即发即弃还是请求回复,数据都处于静止状态以供进一步处理。JMS支持开箱即用的请求-回复,非常简单。Kafka日志是具有持续处理数据的事件流的持久动态数据。Kafka应用程序实时或批量维护和查询状态。数据流是大多数开发人员和架构师的范式转变。这种设计模式非常不同。永远不要尝试使用相同的模式和API在Kafka中重新实现JMS应用程序。这种反模式很可能会失败。请求-响应模式的低效率会导致大量延迟,而HTTP或gRPC适用于某些特定用例。CQRS(CommandQueryResponsibilitySegregation)用Kafka代替“请求-响应”进行流式数据。但是,JMSAPI无法实现CQRS,因为JMS不提供状态功能并且缺少事件溯源功能。请求-响应模式的Kafka示例CQRS是许多Kafka用例的更好设计模式。尽管如此,请求-响应模式也可以用Kafka实现,但要注意:尝试像在JMS消息代理(使用临时队列等)中那样做最终会导致Kafka集群崩溃(因为它的工作方式不同)。KafkaSpringBootKafka模板库有大量使用Kafka构建的请求-回复模式的示例。Kafka模板的Spring文档有很多关于Kafka请求/回复模式的细节。因此,如果您使用Spring,则使用Kafka实现请求/响应模式非常简单。6.持久存储和真正的解耦JMS消息代理使用存储系统来提供高可用性。Kafka的存储系统更先进,可以实现历史事件的长期存储、背压处理和可重放性。Kafka存储远不止JMS的持久化能力当Kai向经验丰富的JMS开发人员解释Kafka存储系统时,他几乎总是得到相同的回答:“我们的JMS消息代理XYZ也有存储,Kafka的好处在哪里?”JMS使用临时存储系统,其中消息仅在处理之前一直存在。消息的长期存储和可重放特性不是为JMS设计的概念。Kafka的核心原则(例如附加日志、偏移量、排序保证、保留时间和压缩主题)提供了许多超出JMS持久性保证的额外好处。背压处理、消费者之间的真正解耦、历史事件的可重放性等是JMS和Kafka最大的区别。阅读Kafka文档以深入了解Kafka存储系统。Kafka的分层存储,通过在Kafka日志中提供更好的扩展性和成本效益的长期存储,也是一个值得深挖的技术细节。7.不同的数据处理方式JMS消息代理提供了简单的服务器端事件处理,例如基于消息内容的过滤或路由。Kafak消息代理不够智能。它的数据处理是在解耦的应用程序/微服务中执行的。JMS服务器端过滤和路由大多数JMS消息代理为服务器端事件处理提供一些功能。这些功能对于某些工作负载非常方便!请注意,服务器端处理通常是有代价的。例如:JMS预过滤可伸缩性问题:代理必须处理很多事情。这可能会以一种隐藏的方式使JMS服务崩溃。JMS选择器(路由)性能问题:消耗了集群40-50%的性能当然,如果能容忍这些缺点,那么也算是一个很棒的特性。Kafka:弱管道和强端点Kafka有意不提供发生在智能端点的服务器端处理。这是一个非常著名的设计模式:弱管道和强终端。缺点是你需要分别在应用程序/微服务/数据产品中实现相关逻辑。这在无服务器环境中不是大问题。在自我管理的环境中,它变得更加复杂。然而,这种架构的一个非常大的好处是:应用程序/技术/编程语言之间真正的解耦,业务单元之间构建业务逻辑和基础架构操作的关注点分离,以及更好的可扩展性和弹性。Kafka以后会不会有一定的服务端处理能力?凯想当然会有。特别是对于小型工作负载,性能和可扩展性的影响应该是可以接受的!但是,风险在于开发人员是否会滥用这些功能。未来会证明Kafka是否具备这种能力。复杂操作与无服务器云可扩展JMS消息代理或Kafka集群的自我管理操作。无服务器产品(应该)承担繁重的操作。不管是JMS还是Kafka,操作一个集群都是复杂的。基本的JMS消息代理相对容易操作(包括主动/被动设置)。但是,这限制了可扩展性和可用性。JMSAPI旨在与单个代理或主动/被动通信以实现高可用性。这个概念涵盖了应用领域。对于JMS消息代理,操作集群非常复杂。来自商业供应商的更高级的消息代理集群更强大,但也更难操作。Kafka是一个强大的分布式系统。完全托管的无服务器云救援在Kafka中,这是不同的。由于Kafka是一个可扩展的分布式系统,云提供商可以构建云原生无服务器产品。构建这样一个完全托管的基础设施仍然非常困难。因此,评价相关的云产品,不能只看他们对外的营销口号!每个Kafka云服务都标榜为“完全托管”或“无服务器”,但大多数都不是。一些云提供商甚至从他们的Kafka云产品中排除了对Kafka的支持。疯狂,但足够真实。因此,检查条款和条件可以成为评估的一部分。9.Java/JVM和任何编程语言JMS专注于JVM编程语言的Java生态系统。而且Kafka是独立于编程语言的。正如JMS(和Java消息服务)的名称所说:JMS是专门为Java编写的。一些代理供应商支持他们自己的API和客户端。这些是该供应商专有的。我过去见过的几乎每个重要的JMS项目都使用Java代码。ApacheKafka也只提供Java客户端。但是供应商和社区为几乎所有编程语言提供了其他语言绑定,以及用于HTTP通信的RESTAPI以从Kafka生成/使用事件。Kafka后端的真正解耦使不同的客户端应用程序能够相互通信,而不管使用的编程语言如何。这种灵活性允许构建适当的领域驱动设计(DDD),其中微服务架构利用Kafka作为中枢神经系统。10.单JMS部署和多区域(包括混合云和多云)Kafka复制JMSAPI是应用程序和代理之间通信的客户端规范。Kafka是一个分布式系统,可为混合云和多云用例提供各种架构。JMS是一种客户端规范,而多数据中心复制是一种代理功能。我不会在这里详述,只是简单地说:JMS消息代理不是为跨地区、洲际或混合/多云环境的复制场景而构建的。ApacheKafka的多集群和跨数据中心部署已成为常态而非例外。各种场景需要多集群的Kafka解决方案。可根据实际情况考虑具体要求和取舍。MirrorMaker(开源)或ConfluentClusterLinking(商业)等Kafka技术支持灾难恢复、聚合分析、云迁移、关键任务延伸部署和全球Kafka部署等用例。11、JMS和Kafka的比较总结以上10个比较维度,可以看出JMS和Kafka有很大的不同。虽然两者也有重叠的领域(例如,消息传递、实时、关键任务),但它们使用不同的技术能力、特性和架构来支持其他功能用例。简而言之,使用JMS代理从A到B的简单且低容量的消息传递。而Kafka通常是众多数据源和数据汇之间的实时数据枢纽(很多人称之为企业架构的中央实时组织系统)。Kafka在任意规模的数据集成和数据处理能力、真正的解耦和事件重放性是与基于JMS的MQ系统的主要区别。但是,尤其是在无服务器云中,不必担心Kafka太强大(太复杂)。无服务器Kafka项目通常以非常低的数量以非常低的成本完成,没有运营负担。然后它可以随着您不断增长的业务而扩展,而无需重建应用程序。12.选择和评价应考虑什么?了解基于JMS的消息代理与ApacheKafka支持的数据流之间的技术差异。评估这两个选项以找到适合您的问题的工具。在消息传递或数据流中,执行更详细的评估。每个消息代理都是不同的,即使它们都符合JMS。同样,所有Kafka产品和云服务在功能、支持和成本方面都不同。因此,开发者应根据实际需求以及两者的用例和局限性做出适当的选择。译者介绍田小宝,社区编辑,资深云计算架构师,互联网老手。拥有超过15年的互联网软件开发和架构经验,并拥有多年的项目管理经验。熟悉云计算、大数据等互联网开发技术。原文链接:https://dzone.com/articles/comparison-jms-message-queue-vs-apache-kafka?fromrel=true
