.markdown-body{word-break:break-word;line-height:1.75;font-weight:400;font-size:15px;overflow-x:hidden;color:#333}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{line-height:1.5;margin-top:35px;margin-bottom:10px;padding-bottom:5px}.markdown-body h1{font-size:30px;margin-bottom:5px}.markdown-body h2{padding-bottom:12px;font-size:24px;border-bottom:1px solid #ececec}.markdown-body h3{font-size:18px;padding-bottom:0}.markdown-body h4{font-size:16px}.markdown-body h5{font-size:15px}.markdown-body h6{margin-top:5px}.markdown-body p{line-height:inherit;margin-top:22px;margin-bottom:22px}.markdown-body img{max-width:100%}.markdown-body hr{border:none;border-top:1px solid #ddd;margin-top:32px;margin-bottom:32px}.markdown-body code{word-break:break-word;border-radius:2px;overflow-x:auto;background-color:#fff5f5;color:#ff502c;font-size:.87em;padding:.065em .4em}.markdown-body code,.markdown-body pre{font-family:Menlo,Monaco,Consolas,Courier New,monospace}.markdown-body pre{overflow:auto;position:relative;line-height:1.75}.markdown-body pre>code{font-size:12px;padding:15px 12px;margin:0;word-break:normal;display:block;overflow-x:auto;color:#333;background:#f8f8f8}.markdown-body a{text-decoration:none;color:#0269c8;border-bottom:1px solid #d1e9ff}.markdown-body a:active,.markdown-body a:hover{color:#275b8c}.markdown-body table{display:inline-block!important;font-size:12px;width:auto;max-width:100%;overflow:auto;border:1px solid #f6f6f6}.markdown-body thead{background:#f6f6f6;color:#000;text-align:left}.markdown-body tr:nth-child(2n){background-color:#fcfcfc}.markdown-body td,.markdown-body th{padding:12px 7px;line-height:24px}.markdown-body td{min-width:120px}.markdown-body blockquote{color:#666;padding:1px 23px;margin:22px 0;border-left:4px solid #cbcbcb;background-color:#f8f8f8}.markdown-body blockquote:after{display:block;content:""}.markdown-body blockquote>p{margin:10px 0}.markdown-body ol,.markdown-body ul{padding-left:28px}.markdown-body ol li,.markdown-body ul li{margin-bottom:0;list-style:inherit}.markdown-body ol li .task-list-item,.markdown-body ul li .task-list-item{list-style:none}.markdown-body ol li .task-list-item ol,.markdown-body ol li .task-list-item ul,.markdown-body ul li .task-list-item ol,.markdown-body ul li .task-list-item ul{margin-top:0}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:3px}.markdown-body ol li{padding-left:6px}.markdown-body .contains-task-list{padding-left:0}.markdown-body .task-list-item{list-style:none}@media (max-width:720px){.markdown-body h1{font-size:24px}.markdown-body h2{font-size:20px}.markdown-body h3{font-size:18px}}
大家好,我是南橘,从接触java到现在也有差不多两年时间了,两年时间,从一名连java有几种数据结构都不懂超级小白,到现在懂了一点点的进阶小白,学到了不少的东西。知识越分享越值钱,我这段时间总结(包括从别的大佬那边学习,引用)了一些平常学习和面试中的重点(自我认为),希望给大家带来一些帮助
目前我在负责新的业务,业务中有一块是调用别的集群的服务进行扣款。之前的同事把这块做成异步通知调用然后等待返回,返回成功就在表里记录成功。由于两块业务在不同的集群,为了确保资金安全,防止出现资金风险,只能依靠第二天的对账来保证,但这种调取方式经常会出现资金差错,又需要人工介入。
和大佬讨论了一会,决定在两个服务之间加入消息队列,通过消息队列来保证数据的一致性,也减少出现资金差错的概率。
那么这一章我们就来学习一下消息中间件的内容。
本地队列按照功能可划分为初始化队列,传输队列,目标队列和死信队列
★初始化队列:用作消息触发功能。
★传输队列:是暂存待传的消息,条件许可的情况下,通过管道将消息传送到其他的队列管理器。
★目标队列:是消息的目的地,可以长期存放消息。
★死信队列:如果消息不能送达目标队列,也不能再路由出去,则被自动放入死信队列保存。
是一个队列定义,用来指定远端队列管理器的队列。使用了远程队列,程序就不需要知道目标队列的位置。
模型队列定义了一套本地队列的属性结合,一旦打开模型队列,队列管理器会按照这些属性动态地创建出一个本地队列。
特点:
终于,不用借大佬的图片,我来给大家画图
特点:
通过这两张图片,我们应该能比较清晰的分辨出这两种模式的区别
只要是通信之间,就会用到协议,就像我们说话的语言一样,不同的语言连通着不同的人群。 消息队列自然也是一样的也是一样,想要互相通信,就要使用同一种协议。
AMQP即Advanced Message Queuing Protocol,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。AMQP是二进制协议,主要特征是面向消息、队列、路由(包括点对点和发布/订阅)。
应用场景:当简单的发布-订阅模型不能满足使用要求。
优点:可靠、通用
STOMP(Streaming Text Orientated Message Protocol)是流文本定向消息协议,是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议。STOMP提供一个可互操作的连接格式,允许客户端与任意STOMP消息代理(Broker)进行交互,通常作用于发布-订阅的模型。
应用场景:信息交换基于文本,要求简单的场景。
优点:命令模式(非topic\queue模式)
XMPP(可扩展消息处理现场协议,Extensible Messaging and Presence Protocol)是基于可扩展标记语言(XML)的协议,多用于即时消息(IM)以及在线现场探测。适用于服务器之间的准即时操作。核心是基于XML流传输,这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息,即使其操作系统和浏览器不同。但XML编码格式占用带宽大。
应用场景:尽可能的简化客户端,复杂的都放在服务端。
优点:通用公开、兼容性强、可扩展、安全性高
JMS是基于JVM消息代理的规范,是对AMQP,MQTT,STOMP,XMPP等协议更高一层的抽象。JMS是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
应用场景:在java体系中,多个服务可以通过JMS进行交互,不需要应用修改代码,但是其对跨平台的支持较差。
优点:异步、可靠
简然要做MQ选型,我们肯定要从大量的MQ做选择,什么样的MQ更适合我们的项目,因此,了解每一种MQ的特征和优缺点是必不可少的。
RocketMQ是阿里系下开源的一款分布式、队列模型的消息中间件,原名Metaq,3.0版本名称改为RocketMQ,是阿里参照kafka设计思想使用java实现的一套MQ。同时将阿里系内部多款MQ产品(Notify、metaq)进行整合,只维护核心功能,去除了所有其他运行时依赖,保证核心功能最简化,在此基础上配合阿里上述其他开源产品实现不同场景下MQ的架构,目前主要多用于订单交易系统。
特点:
优点:
缺点:
使用Erlang编写的一个开源的消息队列,本身支持很多的协议:AMQP,XMPP, SMTP,STOMP,也正是如此,使的它变的非常重量级,更适合于企业级的开发。同时实现了Broker架构,核心思想是生产者不会将消息直接发送给队列,消息在发送给客户端时先在中心队列排队。对路由(Routing),负载均衡(Load balance)、数据持久化都有很好的支持。多用于进行企业级的ESB整合。
特点:
支持多种协议:支持多种消息队列协议;
优点:
缺点:
Apache下的一个子项目。使用Java完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,少量代码就可以高效地实现高级应用场景。可插拔的传输协议支持,比如:in-VM, TCP, SSL, NIO, UDP, multicast, JGroups and JXTA transports。RabbitMQ、ZeroMQ、ActiveMQ均支持常用的多种语言客户端 C++、Java、.Net,、Python、 Php、 Ruby等。
特点:
支持的协议种类多:OpenWire、STOMP、REST、XMPP、AMQP;
代理集群:多个ActiveMQ代理可以组成一个集群来提供服务;
优点:
缺点:
Kafka起初是由LinkedIn公司采用Scala语言开发的一个分布式、多分区、多副本且基于zookeeper协调的分布式消息系统,现已捐献给Apache基金会。它是一种高吞吐量的分布式发布订阅消息系统,以可水平扩展和高吞吐率而被广泛使用。目前越来越多的开源分布式处理系统如Cloudera、Apache Storm、Spark、Flink等都支持与Kafka集成。
特点:
支持同步和异步复制两种高可用机制;
优点:
缺点:
这张图片相比很多同学都看过,那我就放出来再给大家看一下:
因为公司早就做好了MQ的选型,加之对业务场景的判断,最后我还是随大流的选择了RabbitMQ。
从社区活跃度来说:RabbitMQ应该是首选,国内的话有阿里的推广,RocketMQ也慢慢被越来越多的公司所使用。
从技术的实现上来说:公司早就搭建好了完整的Kafka和RabbitMQ的集群,只要不是特殊情况,最后还是需要在这两者之间选择。同时从可靠性、灵活的路由、集群、事务、高可用的队列、消息排序、问题追踪、可视化管理工具、插件系统等方面来看,RabbitMQ也称得上是上佳的选择。
从并发量来说:RabbitmqMQ和RocketMQ都是好的选择。
另外,Kafka 的定位主要在日志等方面, 因为Kafka设计的初衷就是处理日志的,可以看做是一个日志(消息)系统一个重要组件,针对性很强,所以 如果业务方面还是建议选择 RabbitMq 。
还有就是,Kafka 的性能(吞吐量、TPS )比RabbitMq 要高出来很多。
因为实际工作的时候讨论到了MQ,想了想在研究MQ的时候就顺便把文章整理出来了。因为公司早早搭建好了集群,也没必要我自己去搭建。但是,研究了一段时候后心里却有一点小想法,下一章会讲一讲MQ具体的内容吧,包括MQ的集群、MQ实现顺序消息、实现ACK之类的,不会像这章一样多是说特点了。 同时需要思维导图的话,可以联系我,毕竟知识越分享越香!