Java消息服务
2010年1月
电子工业出版社
Mark Richards,Richard Monson-Haefel,David A.Chappell
336
闫怀志
无
获邀担纲《Java消息服务(第2版)》的翻译,我的思绪一下回到了10年前。当时,不仅是初出茅庐的我,甚至很多资深的同行,都在为不同系统之间的信息交换而头疼不已:一方面,数据集成和系统整合的需求非常强烈;另一方面,信息交换的技术实现不仅难度很大,而且实现方式也因各有利弊而难于选择。在技术路线的选择上,我们究竟何去何从?这在“雾里看花”的当年,真不啻于一场赌博。因为后来的事实证明,即便是其中较为常用的CORBA、DCOM、RMI等远程过程调用(RPC)中间件技术,虽可以解决一些问题,但它们在健壮性、性能和可伸缩性方面的表现很难让人满意。 期间,从我一位留美的同学处,偶然获悉了Java消息服务(JMS)机制,令我闻之一震——它很好地解决了让我困惑良久的在不同系统间进行数据和功能共享的问题。我不仅自己如获至宝,还因为职业的关系,在我的领地——三尺讲台上竭力传播这一思路。 简而言之,JMS是1999年由 Sun Microsystems领衔开发的一种访问消息系统的方法,也就是供Java程序员使用的面向消息的中间件(MOM)。这种基于消息传送的异步处理模型,具有非阻塞的调用特性。发送者将消息发送给消息服务器,服务器会在合适的时候再将消息转发给接收者;发送和接收采用异步方式,这就意味着发送者无须等待,发送者和接收者的生命周期也无需相同,而且发送者还可以将消息传给多个接收者。如此一来,这种异步处理方式就大大提升了应用程序的健壮性、性能和可伸缩性,使数据集成和系统整合工作变得易如反掌,特别是在分布式应用上让同步处理方式望尘莫及。Java消息服务作为一个与具体平台无关的API,已经得到绝大多数MOM提供商的支持。 本书深入浅出地讲解了JMS规范的底层技术、Java类和接口、编程模型及其不同实现。尤其值得指出的是,当年我学习Java消息服务的启蒙教材,正是O’Reilly在2000年出版的本书第1版。所以看到第2版,真是一见如故。较之9年前的第1版,除了著名的Richard Monson-Haefel和David A.Chappell之外,又有消息传送机制、面向服务体系结构和事务管理领域的公认权威Mark Richards来担纲第一作者。我在仔细研读之后发现,本版继承了初版的优点,但在内容及结构方面有了很大变化,某些地方甚至可以说是“质”变,究其原因主要有二:其一,初版两年后(即2002年3月)发布了JMS 1.1,统一了消息域。新版必须为适用JMS 1.1而修订;其二,经过10年的发展,Java平台和消息传送机制日臻完善,消息驱动bean、Spring消息框架、事件驱动体系结构(EDA)、面向服务体系结构(SOA)、RESTful JMS接口,以及企业服务总线(ESB)等新的消息传送技术也层出不穷。这些亮点不仅是第2版的精华所在,它们本身也代表了Java消息服务技术的发展方向。 当然,任何一项技术都是有利有弊的,也都会经历发展、鼎盛直至消亡的生命旅程,Java消息服务也不例外。无须讳言,近些年来在异构系统集成领域,Java消息服务就遭到了Web服务的强力挑战。不过,在Web服务解决可靠性等问题之前,Java消息服务仍然是异构系统集成的不二之选。我相信,如果您读完了本书,并切实领会了JMS的精髓和要义之后,会十分认同这个观点。 翻译一本书,弄不好就会是“出力不讨好的苦差”,因为无论是技术本身、原著水平、读者领悟力等哪个环节出了问题,板子通常都会打在翻译者身上。当然就本书而言,JMS技术本身、原著的水平和读者的领悟力都不会有什么问题。所以,既然我愿意做这样的知识传播者,那就要勇于承担所有的责任。套用我所敬仰的一位长者之言:我只希望在我翻译完以后,全体读者能说一句,他是一个负责的译者,不是敷衍了事的译者,我就很满意了。如果他们再慷慨一点,说闫怀志某些地方译得还不错,我就谢天谢地了。 本书翻译期间得到了电子工业出版社博文视点公司徐定翔、白爱萍、杨绣国、陈元玉、许莹等编辑的热心帮助。书中绝大部分术语采用了Sun公司的标准译法,在此一并致谢。最后,我要感谢家人的支持,否则完成这样一项工作几乎是不可想象的。由于译者水平有限,加之时间较紧,虽已尽力避免错误,难免仍有疏漏,恳请广大读者将意见和建议发至:bityhz001@sina.com,不胜感激。 闫怀志 2009年秋于北京中关村
《Java消息服务(第2版)》深入浅出地讲解了JMS1.1规范的底层技术、Java类和接口、编程模型及其不同实现等Java消息服务(JMS)和消息传送机制关键技术。通过对支持点对点和发布/订阅“消息传送”的标准API的完全解读以及具体实例,介绍了如何利用“厂商无关”的JMS来解决许多体系结构的面临的挑战,比如异构系统和应用程序集成、提高可伸缩性、降低系统瓶颈、支持并发处理,以及提升灵活性和敏捷性等。
推荐序 I前言 III第1章 消息传送机制基础 11.1 消息传送机制的优点 31.1.1 异构集成 31.1.2 缓解系统瓶颈 31.1.3 提高可伸缩性 41.1.4 提高最终用户生产率 41.1.5 体系结构灵活性和敏捷性 51.2 企业消息传送 51.2.1 集中式体系结构 71.2.2 分散式体系结构 71.2.3 混合体系结构 81.2.4 以集中式体系结构作为模型 81.3 消息传送模型 91.3.1 点对点模型 101.3.2 发布/订阅模型 101.4 JMS API 111.4.1 点对点API 131.4.2 发布/订阅API 141.5 实际场景 141.5.1 面向服务体系结构 151.5.2 事件驱动体系结构 161.5.3 异构平台集成 161.5.4 企业应用集成 171.5.5 企业到企业 171.5.6 地理分散 181.5.7 信息广播 181.5.8 构建动态系统 181.6 RPC和异步消息传送 211.6.1 紧密耦合的RPC 211.6.2 企业消息传送 23第2章 编写一个简单的示例程序 252.1 聊天应用程序 252.1.1 从Chat示例开始 282.1.2 分析源代码 302.1.3 会话和线程 39第3章 深入剖析一条JMS消息 413.1 消息头 423.1.1 自动分配的消息头 433.1.2 开发者分配的消息头 463.2 消息属性 473.2.1 应用程序特定的属性 473.2.2 JMS定义的属性 493.2.3 提供者特定的属性 503.3 消息类型 503.3.1 Message 503.3.2 TextMessage 513.3.3 ObjectMessage 523.3.4 BytesMessage 533.3.5 StreamMessage 563.3.6 MapMessage 583.3.7 只读消息 603.3.8 客户端确认的消息 613.3.9 消息的互操作性和可移植性 61第4章 点对点消息传送模型 634.1 点对点模型概览 634.1.1 何时使用点对点消息传送模型 664.2 QBorrower和QLender应用程序 674.2.1 配置并运行应用程序 674.2.2 QBorrower类 694.2.3 QLender类 764.3 消息关联 814.4 动态队列对受管队列 834.5 使用多个接收者实现负载均衡 844.6 分析一个队列 85第5章 发布/订阅消息传送模型 875.1 发布/订阅模型概览 875.1.1 何时使用发布/订阅消息传送模型 895.2 TBorrower和TLender应用程序 905.2.1 配置并运行应用程序 905.2.2 TLender类 925.2.3 TBorrower类 965.3 持久订阅者和非持久订阅者 1005.4 动态订阅者和受管订阅者 1015.5 取消订阅动态持久订阅者 1045.6 临时主题 104第6章 消息过滤 1076.1 消息选择器 1096.1.1 标识符 1106.1.2 常量 1116.1.3 比较运算符 1116.1.4 算术运算符 1136.2 声明一个消息选择器 1146.3 消息选择器示例 1166.3.1 管理HMO的索赔申请 1166.3.2 关于存货的特定报价通知 1166.3.3 优先级处理 1166.3.4 证券交易订单审计 1176.4 未传送语义 1176.5 设计注意事项 118第7章 保证消息传送和事务 1257.1 保证消息传送 1257.1.1 消息自主性 1267.1.2 保存并转发消息传送 1267.1.3 消息确认和故障情况 1267.2 消息确认 1277.2.1 AUTO_ACKNOWLEDGE 1277.2.2 DUPS_OK_ACKNOWLEDGE 1327.2.3 CLIENT_ACKNOWLEDGE 1327.3 消息组和确认 1337.3.1 在应用程序中处理消息的重新传送 1347.3.2 消息组示例 1347.3.3 消息编组和多个接收者 1437.4 事务性消息 1457.4.1 创建并使用一个JMS事务 1477.4.2 事务性会话示例 1477.4.3 分布式事务 1507.5 丢失连接 1517.5.1 ExceptionListener示例 1527.6 停用消息队列 153第8章 Java EE和消息驱动bean 1558.1 Java EE概览 1558.1.1 企业级JavaBean 1568.2 企业级JavaBean 3.0(EJB3)概览 1578.2.1 简化bean开发 1588.2.2 依赖注入 1588.2.3 简化回调方法 1598.2.4 通过编程方式默认 1598.2.5 拦截器 1608.2.6 Java持久性API 1628.3 Java EE中的JMS资源 1628.3.1 JNDI环境命名上下文(ENC) 1648.4 消息驱动bean 1668.4.1 并发处理和可伸缩性 1688.4.2 定义消息驱动bean 1688.5 消息驱动bean用例 1718.5.1 消息门面 1718.5.2 转换和路由选择 173第9章 Spring和JMS 1779.1 Spring消息传送体系结构 1779.2 JmsTemplate概览 1809.2.1 Send方法 1819.2.2 convertAndSend方法 1819.2.3 receive和receiveSelected方法 1829.2.4 receiveAndConvert方法 1839.3 连接工厂和JMS目的地 1849.3.1 使用JNDI 1849.3.2 使用本地类 1879.4 发送消息 1899.4.1 使用send方法 1909.4.2 使用convertAndSend方法 1919.4.3 使用非默认JMS目的地 1939.5 同步接收消息 1959.6 消息驱动POJO 1989.6.1 Spring消息侦听器容器 1989.6.2 MDP可选方案1:使用MessageListener接口 1999.6.3 MDP可选方案2:使用SessionAwareMessageListener接口 2019.6.4 MDP可选方案3:使用MessageListenerAdapter 2029.6.5 消息转换限制 2079.7 Spring JMS命名空间 2089.7.1 消息属性 2099.7.2 元素属性 211第10章 部署注意事项 21310.1 性能、可伸缩性和可靠性 21310.1.1 确定消息吞吐量需求 21310.1.2 测试实际场景 21410.2 组播与否 21710.2.1 TCP/IP 21810.2.2 UDP 21810.2.3 IP组播 21810.2.4 基于IP组播的消息传送 21910.2.5 关键要点 22110.3 安全性 22210.3.1 认证 22210.3.2 授权 22310.3.3 安全通信 22410.3.4 防火墙和HTTP通道 22410.4 连接外部世界 22510.5 桥接到其他消息传送系统 227第11章 消息传送设计注意事项 22911.1 内部目的地与外部目的地 22911.1.1 内部目的地拓扑结构 23011.1.2 外部目的地拓扑结构 23111.2 请求/应答消息传送设计 23211.3 消息传送设计反模式 23611.3.1 单用途队列 23611.3.2 过度使用消息优先级 24011.3.3 滥用消息头 240附录A Java消息服务API 245附录B 消息头 265附录C 消息属性 277附录D 安装和配置ActiveMQ 285索引 291
无