消息中间件是分布式系统中的重要组件,在实际工作中常用消息中间件进行系统间数据交换,从而解决应用解耦、异步消息、流量削峰等问题,实现高性能、高可用、可伸缩和最终一致性架构。目前市面上可供选择的消息中间件有RabbitMQ、ActiveMQ、Kafka、RocketMQ、ZeroMQ、MetaMQ等。本书结合作者近年来在实际项目中使用消息中间件的经历和踩过的一些坑总结整理而成,主要介绍消息中间件使用的背景、基本概念,以及常用的四种消息中间件产品在各个业务场景中的使用案例。作为案例介绍,虽然不能对各种消息中间件产品的所有特性做详细说明,但是希望读者可以通过每章中的案例讨论和实践建议得到启发,为在实际工作中进行产品选型、业务场景方案制定、性能调整等提供思路。
详解消息中间件的高可用、高性能配置和原理
常用的四种消息中间件产品在各个业务场景中的使用案例
大约在五年前,那时我参与的项目到了收尾阶段,工作不太忙,觉得写了好几年业务代码没什么意思,就想找点有技术含量的东西研究。有一次去山西路上的军人俱乐部闲逛,在三楼一家书店的角落里看到一本讲Tomcat源码的书,翻了二三十页觉得挺有意思,讲的很多关于Tomcat实现的由来以前我从来都不知道,买回家不到一个星期就看了一遍。遗憾的是,这本书讲的Tomcat版本有点老,在实际工作中一般都用到5以上的版本了。正好当时我也有点时间,就决定分析一下最新的Tomcat 7的源码,并发表在了ITeye网站上。作为老牌的Web服务器,Tomcat 7的内容非常丰富,写这个系列文章的主要部分,前后花了一年的时间,由此我也就逐渐养成了坚持写博客总结一段时间以来工作和学习到的知识的习惯。
这几年我也常劝很多朋友多写点东西总结,有时作为面试官遇到技术还不错的面试者会问问有没有博客,如果有的话一般会在面试成绩上额外加点分。据我的观察,几乎每一个程序员都知道写博客的好处,但真的动手去写的人实际很少,一个很重要的原因,就是很多人会说“我又不是大牛,写出来的东西没人看,那还有啥意义?”我的回答是,不是牛人一样可以写博客。有一次我碰到一个项目用到一些以前没接触过的新技术,在项目搭建过程中报出错误,但错误信息提示不明确,只说某地方有一个配置校验不通过的异常,到底要通过什么方式解决该问题文档上也没写,只能“Google”一下,在搜索结果的第一页就看到有人遇到了同样的问题、一样的环境和最终的解决办法,一试之下果然奏效。于是就翻了翻他的博客目录,写的大部分内容都是很基础的,有的可能就是对某个技术里的某个特性的介绍,没有高深莫测的东西,也没有长篇大论,但正好里面有篇文章解决了困扰我大半天的问题,显然这篇博客对我来说就非常有价值。在实际工作和学习中我们会遇到很多问题,有的问题经过千方百计翻遍资料甚至查看源码实现,经过一番痛苦折磨终于解决了,那么就可以把这个过程整理成博客,既对自己所学的知识进行了总结、积累了经验,又能给其他可能会碰到类似问题的人提供帮助,分享出去,让更多的人受益,这就是我认为的写博客的价值。
也就是在这个过程中,有一天我接到了博文视点陈晓猛编辑的邀请,说看了我写的关于消息中间件介绍的几篇文章,想让我出一本与之相关的书,系统介绍一下相关技术。这真是一个让人兴奋的消息,读了这么多年书,现在居然有机会出自己的书了。在欣喜之外还有忐忑,担心我的经验与水平有限,写出来的东西耽误了读者的时间,但是经过陈编辑的多次鼓励,我决定大胆尝试一下。在写这本书之前,其实国内已经有一些介绍消息中间件的书了,但这些书大都是针对某个具体产品的详细介绍,比如与RabbitMQ和ActiveMQ相关的中文、英文读物。市面上缺少的是针对主流消息中间件的整体性介绍,以及结合实际消息应用场景的案例说明,因此我打算写一本这样的书。本书选取了我认为市面上应用最广泛的四种消息中间件产品,即RabbitMQ、ActiveMQ、Kafka和RocketMQ,介绍这些消息中间件的来源、特性、Java 语言使用的示例和结合具体业务场景的应用案例,最后给出在实际项目中使用时的一些建议和需要综合权衡的技术要点,希望能对读者的工作有一定的帮助。所以,本书面对的读者主要是具备一定的Java功底,尤其是对消息中间件感兴趣并有一定实际使用经验的工程师。本书并不会对每种产品的特性都做非常详细的阐述,因为这些最权威、最详尽的资料都可以从官网中获得,书中内容聚焦于实践,也建议读者能多动手实践一下,这样学到的东西才是自己的。
本书内容
全书共6章,第1章和第2章介绍消息中间件的背景和所涉及的常见概念,第3~6章分别介绍一种消息中间件产品,读者可自行选择阅读。
第1章:介绍消息队列技术的背景,包括使用场景和消息队列的功能特点,并设计了一个简单的消息队列。
第2章:介绍消息队列中常用的消息协议,包括每个消息协议的历史背景、主要概念和基于该协议的消息通信过程。本章所介绍的协议也是接下来理解各种消息中间件产品的基础。
第3章:具体介绍RabbitMQ的特点、主要概念和Java使用示例,接着通过使用RabbitMQ实现异步处理和消息推送的功能,最后给出在工作中使用RabbitMQ时的一些实践建议。
第4章:具体介绍ActiveMQ的特点、基本概念和Java使用示例,接着通过使用ActiveMQ实现消息推送分布式事务的功能,最后给出在工作中使用ActiveMQ时的一些实践建议。
第5章:具体介绍Kafka的特点、主要概念和Java使用示例,接着通过使用Kafka实现用户行为数据采集、日志收集和流量削峰的功能,最后给出在工作中使用Kafka时的一些实践建议。
第6章:具体介绍RocketMQ的特点、主要概念和Java使用示例,接着通过使用 RocketMQ的特性实现消息顺序处理和分布式事务的另外一种解决方案,最后给出在工作中使用RocketMQ时的一些实践建议。
致谢
虽然这是我写的第一本书,但我不是唯一的作者。书中的很多内容简介分散于各种书籍、标准文档、研究论文、会议演讲、博客,甚至微博、Twitter中关于某个消息中间件特性的讨论之上,感谢互联网,是前面许许多多的实践者成就了这本书。工作这么多年,我有幸与很多在软件开发领域有不懈追求的同仁共事,他们扩展了我在很多方面的知识,有很多人帮助我审阅过部分手稿。感谢他们的帮忙,从他们身上我学到了许多宝贵的经验,更感谢他们为本书提供的许多宝贵建议。感谢博文视点的编辑,这本书能够如期出版,离不开你们的敬业精神与一丝不苟的工作态度,我为你们点赞!
倪炜
2018年6月于南京
commitAsync在成功提交或碰到无法恢复的错误之前会一直重试,而commitAsync却不会(比较的两个都是commitAsync,有一个应该是commitSync)
12页produce和consume方法为静态方法,13页MqClient调用时new了对象以后进行的调用,有点不太一致,但问题不大。
示例代码为:
public void sendMessageJMS11(ConnectionFactory connectionFactory, Queue queueString text){...}
应该改为:
public void sendMessageJMS11(ConnectionFactory connectionFactory, Queue queue, String text){...}
第57页代码问题同上