写点什么

Mark Richard 的《Java 消息服务》第二版

  • 2010-02-01
  • 本文字数:3928 字

    阅读完需:约 13 分钟

Mark Richards 的新书《Java 消息服务》第二版覆盖主题包括异步消息和 Java 消息服务( JMS )。JMS规范自2000 年本书第一版出版以来已经取得了长足发展。

在新书中,Mark 讨论了消息的基本概念,消息产品厂商的常用架构以及JMS 的两种编程模型:发布- 订阅模型点对点模型。该书还涉及到了如消息过滤、有保证的消息传递及事务等高级专题。

Mark 讨论了 Java EE 对 EJB 3.0 规范的消息传递的实现(使用消息驱动 Bean)以及 Srping 框架使用 Srping JMS 模板和消息驱动对象(MDPs)实现的 JMS 消息传递。

该书以对消息服务的设计结束,包括使用内部与外部目的地,请求 / 响应处理以及一些常见消息传递反模式,例如单一目的队列,过度使用消息优先权和误用消息头。书中使用的例子代码是 ActiveMQ ,一个开源的消息容器。

InfoQ 与 Mark 讨论了他这本新书,包括写作的主要动机以及其他议题。访谈的议题包括在实现消息应用中和企业服务总线(ESB)架构中 Spring 消息驱动对象(MDP)的作用。

我们还从《Java 消息服务》一书中为我们的读者摘取了一段(314K 的 PDF 文档)摘要

InfoQ:写作本书第二版的主要动机是什么?

Mark Richards (MR): 当别人要求我修订本书的第一版时,我没想到这会需要很大的努力,尤其是本书的第一版写得非常好,从 Java 社区得到的好评如潮(感谢 Richard Monson-Heafel 和 David Chappell 为第一版所作的贡献 )。然而,当我开始修订原稿的手稿时,我很快发现自从第一版以来的 10 年中消息领域发生了巨大的变化。这种变化不仅仅是在于 JMS 的版本升级(从 JMS1.02 到 JMS1.1)方面,而且还在于消息的使用方式方面。新技术、工具以及科技都在冲击着市场,包括消息驱动 Bean(MDB),Spring 消息驱动对象(MDP),企业级开源产品提供者例如 ActiveMQ,RESTFul JMS 接口,面向服务的架构以及企业服务总线中间件产品。此外,随着 Java 平台日渐成熟,我们使用消息的方式也日趋成熟。从与异构平台和组件的互操作到 高速异步并发处理,消息已经在我们今天使用的大多数架构中证实了它的价值。因此,我在第二版中重写了本书 75% 的内容。

我写本书的第二版的主要动机是我对于技术的激情与对消息领域的强烈兴趣和丰富经验的联合结果。这个写作机会让我得以把我的新生命融入一本伟大的著作中,帮 助原著传播什么是 JMS API 以及如何使用它来解决一些非常有趣的问题。在第二版中有很多新内容,讲述了我们今天如何使用消息。

InfoQ:Spring 的消息驱动对象(MDP)已经成为 EJB 模型中的消息驱动 Bean(MDB)代替设计。你在书中写 到了 Spring 的 MDP 以及使用消息驱动 Bean(MDB)的 J2EE 方式来实现异步消息传递。Spring 作为一个完善的 DI 框架,它的 MDP 架构相 对于 MDB 有什么优势呢?

MR: 绝对有优势。EJB 与 Spring 框架都支持容器管理的异步监听器。然而,MDB 架需要 EJB 的支持,其支持是非常简单而直接的,仅仅提供一种类型的异步消息监听器。一个 MDB 必须实现 javax.jms.MessageListener 接口,需要你实现 onMessage() 方法,该方法接收一个 javax.jms.Message 类型的消息对象作为参数。

在另一方面,Spring 支持三种类型的异步消息监听器(MDP)。第一种类型的 MDP 与对应的 MDB 最接近,实现了 javax.jms.MessageListener 接口和 onMessage() 方法,需要你处理一个 javax.jms.Message 类型的消息 。第二种类型与第一种类似,但是实现了 Spring 框架的接口 SessionAwareMessageListener,允许 javax.jms.Session 对象与消息对象一起传入 onMessage() 方法,这样就易于在收到消息后发送或者响应消息。第三种类型 MDP(我最喜爱的类型)是一个真正的 POJO,使用一个 Spring 的 MessageListenerContainer。通过第三种 MDP,Spring 会自动为你处理所有的消息变换,允许你构造一个异步的消息监听器 (MDP),该监听器有一个诸如 processTrade() 的方法,该方法接收一个从消息负载中得到的包含一些 XML 的字符串参数,而不是像非描述性的 onMessage() 方法那样接受一个消息对象。

基本上,Spring 的 MDP 删除了与消息相关的繁文缛节,允许你专注于业务逻辑。这真的很酷,值得一看。

InfoQ:Servlet 3.0 规范为 web 层带来了异步通信。你认为 Servlet 3.0 规范会对企业软件开发和有异步处理需求的案例带来什么样的冲击?这对于传统的、也许不像 servlet 模型那么轻量级的使用 JMS 技术的异步消息编程意味着什么?

MR:首先,我不认为我同意 servlet 模型比一个简单的消息框架(特别是使用 Spring 时)还轻量级。我没有发现 Servlet 3.0 规范会代替现存的或者将来的 JMS 消息系统。消息系统提供了 Servlet 3.0 规范异步通信方面之外的几个重要方面,包括高级的负载平衡,更好的监控能力,以及也许是最重要的——确保交付能力。我认为不考虑消息处理 层,Servlet 3.0 规范异步通信方面会对通常的消息(包括 JMS 和非 JMS)有益,因为它会增加人们对 Java 平台上异步通信重要性的认识,然而,我的观点是它不会成 为强大而简单的 JMS 消息框架的代替品,尤其是目前的消息产品 WebSphere MQ 和 Apache ActiveMQ 正在向 RESTful 消息接口方面努力。

InfoQ:企业服务总线(ESB)模式在异步消息 /JMS 架构模型中适用于什么方面?

MR:企业服务总线可以通过各种协议与消费者和生产者(包括内部的和外部的)通信,包括 HTTP 和 JMS。这些协议都可以发 送和接收 SOAP 消息和普通 XML(或者其他用于特定用途的消息负载格式)。然而,大多数企业服务总线在防火墙之后作为一个消息中间件工作,提供媒介、路 由和转换功能(和其他功能)。因此,我认为 JMS 消息机制是比 HTTP 之上的 web service 好的多的选择,在访谈中我已经提到了许多原因 —— 更高的可靠性,更低的复杂性,更优的负载平衡,更好的监控,更好的性能以及提供确保投递的能力。

毫不奇怪,在大多数企业集成模式中,ESB 是基于消息的概念的。大多数 ESB 允许你在 HTTP 和 JMS 协议之间方便的切换。除非你有来自外部互联网的客户请求,我建议你坚持使用 JMS 而不要切换到 HTTP。

InfoQ:什么是开发者和架构师在架构和构建现实的 JMS 系统时应该采用的最佳实践和“秘笈”?

MR:我最喜爱的“秘笈”是为一个消息设置过期时间。因为 JMS API 在 javax.jms.Message 对象中通过标准的 get 和 set 方法暴露了消息头属性,开发者经常试图直接调用 message.setJMSExpiration() 来设置消息过期。然而,除了 JMSReplyTo、JMSCorrelationID 和 JMSType 之外,JMS 提供者会重写每个消息头。因此,当你通过 set 方法直接设置消息头属性使消息过期,该消息实际上永远不会失效。你需要使用 MessageProducer 接口的 setTimeToLive() 方法来设置消息过期。同样,调用 message.setJMSPriority() 不会设置消息的优先级。你需要使用 MessageProducer 接口的 setPriority() 方法。

开发者应该意识到还有许多设计实践和陷阱,例如使用太少(或者太多)队列,使用太少(或者太多)并发监听器,什么时候应该使用消息过滤而不是多队列或者主 题,什么时候使用点到点消息模型,什么时候使用发布 - 订阅模型。所有这些场景(以及更多的场景)都在新版的 JMS 书中谈到了。

InfoQ: 异步消息在面向服务架构 ( SOA ) 中扮演着重要角色,不管是作为事件驱动架构 ( EDA ) 还是 ESB 设计的一部分。你认为在 SOA 领域中 JMS 扮演着什么角色?

MR:在 SOA 环境中部署的服务应该高度解耦。服务可能有在多种语言和平台上实现,包括一些遗留的主机系统。SOA 的伟大之 处之一是服务实现完全独立于服务定义。假如你不改变服务契约,那么你就可以替换、修改该服务实现,而客户根本不知道服务的实现发生了变化。这里是消息系统 大显身手之处——与通过消息来解耦组件和服务相比,还有什么更好的方式?大多数企业级商业和开源的消息产品都提供异构的通信,也就是说 Java 可以给一个 C#应用或者 CICS 组件发送一个消息。在 SOA 中消息是解耦解决方案的至关重要的一部分。

InfoQ:对于 JMS 规范,你希望会有什么新特征,或者现有特征有什么变化?

MR: JMS1.1 规范在 7 年前的 2002 年三月发布。目前没有更新 1.1 规范的动向,这说明当前的 JMS 规范实际上是非常稳定的,经过深思熟虑的。我希望规范 变化的或者增加的特征是在发布 - 订阅模型中定义子主题,这样可以增加一致性。许多消息产品供应商允许你定义主题的一个继承结构。例如,你可能有一个叫做 “ERRORS”的根主题。该主题下也许有两个孩子主题(或者子主题),定义为“ERRORS.VALIDATION"和“ERRORS.DB”。这些将 来可以分解为验证或者数据库类型错误。你可以定义一个订阅者,使用一个通配符“ERRORS.*”来接收所有的错误。或者你订阅 “ERRORS.VALIDATION.*”来接收所有验证错误。最终,你通过直接订阅“ERRORS.VALIDATION.XMLPARSE”得到所 有 XML 解析验证错误。

因为 JMS1.1 规范没有定义如何处理子主题,所以每个消息产品都实现的不同。例如, IBM WMQ 定义分隔符为一个斜杠(“/”),通配符为一个星号(“*”),而 SonicMQ 是用一个店(“.”)作为主体分隔符,一个星号(“*”)作为通配符。 SwiftMQ 使用一个百分号(“%”)作为通配符,等等。如果这成为标准,那么所有产品都会一致,这样会很好。

InfoQ:对于本书和 JMS 的话题你还有其他评论么?

MR:我相信消息技术(特别是 JMS)正在迅速成为开发者、设计者和架构师的一项“核心能力”。对于消息技术和 Java 平台来说现在都是激动人心的时刻。新出版的《Java 消息服务》第二版会帮助开发者理解 JMS APi 和常用的消息概念,从而很快地迎头赶上。

InfoQ:谢谢你 Mark。


感谢宋玮对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。

2010-02-01 10:595529
用户头像

发布了 47 篇内容, 共 11.9 次阅读, 收获喜欢 3 次。

关注

评论

发布
暂无评论
发现更多内容

旁门左道:借助 HttpClientHandler 拦截请求,体验 Semantic Kernel 插件

不在线第一只蜗牛

Java c++ 开发语言

一条Linux命令打败99%的运维

伤感汤姆布利柏

AI 大模型微调训练营第 0 期 -- 毕业总结

Jabez

正式发布后的一年,我们都做了什么? | Sermant 2023年度总结

华为云开源

开源 微服务 服务治理 sermant

多人协同开发场景,如何做到高效发布

阿里巴巴云原生

阿里云 微服务 云原生 云效

spark为什么比mapreduce快?

京东科技开发者

安全利器!龙蜥推出机密计算远程证明服务—OAAS 诚邀广大用户测试

OpenAnolis小助手

开源 安全 龙蜥社区 机密计算 OAAS

为什么程序员不能一次性写好,需要不停改bug?

伤感汤姆布利柏

Sora文生视频模型深度剖析:全网独家指南,洞悉98%关键信息,纯干货

汀丶人工智能

Pika sora 文生视频 文生视频模型

分布式场景怎么Join | 京东云技术团队

京东科技开发者

技术分享 | 神级程序员都在用什么工具?

互联网工科生

IntelliJ IDEA 数据源 JNPF

技术专栏丨Rust 语言简介及其在 Fabarta 技术栈中的应用

Fabarta

户外全彩LED显示屏的验收标准

Dylan

全彩LED显示屏 户外LED显示屏 led显示屏厂家

区块链游戏解说:什么是 Nine Chronicles

Footprint Analytics

区块链游戏

人工智能的起源和应用场景

小齐写代码

提升网络灵活性,SD-WAN助您快速应对备用线路需求

Ogcloud

网络 SD-WAN 企业网络 SD-WAN组网 SD-WAN服务商

面试官:如何实现多级缓存?

王磊

Java 面试

跨国制造商部署SD-WAN提升全球业务案例分析

Ogcloud

SD-WAN 企业组网 SD-WAN组网 SD-WAN服务商 SDWAN

APISIX 可观测性最佳实践

观测云

APISIX

京东商品详情数据采集方法代码展示

tbapi

京东API接口 京东商品详情接口

多人协同开发场景,如何做到高效发布

阿里云云效

阿里云 云原生 云效

如何做代币分析:以 BNB 币为例

Footprint Analytics

Token 代币 bnb

Mark Richard的《Java消息服务》第二版_Java_Srini Penchikala_InfoQ精选文章