消息中间件MQ知识概括
Posted GeorgeLin98
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了消息中间件MQ知识概括相关的知识,希望对你有一定的参考价值。
消息中间件MQ知识概括
MQ简介
传统的http请求存在那些缺点:
-
Http请求基于请求与响应的模型,在高并发的情况下,客户端发送大量的请求达到 服务器端有可能会导致我们服务器端处理请求堆积。
-
Tomcat服务器处理每个请求都有自己独立的线程,如果超过最大线程数会将该请求缓存到队列中,如果请求堆积过多的情况下,有可能会导致tomcat服务器崩溃的问题。
-
所以一般都会在nginx入口实现限流,整合服务保护框架。
-
http请求处理业务逻辑如果比较耗时的情况下,容易造成客户端一直等待,阻塞等待过程中会导致客户端超时发生重试策略,有可能会引发幂等性问题。
-
注意事项:
接口是为http协议的情况下,最好不要处理比较耗时的业务逻辑,耗时的业务逻辑应该单独交给多线程或者是mq处理
。
耗时解决方案对比:
同步发送http请求:
客户端发送请求到达服务器端,服务器端实现会员注册业务逻辑。
①insertMember() --插入会员数据 1s
②sendSms()----发送登陆短信提醒 3s
③sendCoupons()----发送新人优惠券 3s
④总共响应需要6s时间,可能会导致客户端阻塞6s时间,对用户体验
不是很好。
多线程处理业务逻辑:
用户向数据库中插入一条数据之后,在单独开启一个线程异步发送短信和优惠操作,客户端只需要等待1s时间。
①优点:适合于小项目,实现异步
②缺点:有可能会消耗服务器cpu资源资源(线程属于CPU资源),没有实现解耦。
Mq处理业务逻辑:
先向数据库中插入一条会员数据,让后再向MQ中投递一个消息,MQ服务器端在将消息推送给消费者异步解耦处理发送短信和优惠券。
①优点:MQ可以实现异步/解耦/流量削峰问题,适合大项目。
远程调用服务(RPC)和消息(Message Queue)对比:
- 结构对比:
RPC系统结构:
+----------+ +----------+
| Consumer | <=> | Provider |
+----------+ +----------+
Consumer调用的Provider提供的服务。
Message Queue系统结构:
+--------+ +-------+ +----------+
| Sender | <=> | Queue | <=> | Receiver |
+--------+ +-------+ +----------+
Sender发送消息给Queue;Receiver从Queue拿到消息来处理。
- 功能特点:
在架构上,RPC和Message的差异点是,Message有一个中间结点Message Queue,可以把消息存储
。 - 消息的特点:
①Message Queue把请求的压力保存一下,逐渐释放出来,让处理者按照自己的节奏来处理。
②Message Queue引入一下新的结点,让系统的可靠性会受Message Queue结点的影响。
③Message Queue是异步单向的消息。发送消息设计成是不需要等待消息处理的完成。
④所以对于有同步返回需求,用Message Queue则变得麻烦了
。 - RPC的特点:
①同步调用,对于要等待返回结果/处理结果的场景,RPC是可以非常自然直觉的使用方式
。
②RPC也可以是异步调用。由于等待结果,Consumer(Client)会有线程消耗
。
③如果以异步RPC的方式使用,Consumer(Client)线程消耗可以去掉。但不能做到像消息一样暂存消息/请求,压力会直接传导到服务Provider
。 - 适用场合说明:
①希望同步得到结果的场合,RPC合适。
②希望使用简单,则RPC;RPC操作基于接口,使用简单,使用方式模拟本地调用。异步的方式编程比较复杂。
③不希望发送端(RPC Consumer、Message Sender)受限于处理端(RPC Provider、Message Receiver)的速度时,使用Message Queue。 - 详细链接:远程调用服务(RPC)和消息(Message Queue)对比及其适用/不适用场合
消息中间件简介:
- 消息中间件基于队列模型实现异步/同步传输数据
- 作用:可以实现
支撑高并发
、异步解耦
、流量削峰
、降低耦合度
。 - Mq应用场景有那些:
①异步发送短信
②异步发送新人优惠券
③处理一些比较耗时的操作
JMS
JMS简介:
- JMS(java message service):由Sun公司早期提出的消息标准,是一个Java平台中关于面向消息中间件(MOM)的API,旨在为java应用提供统一的消息操作。
- JMS 定义了JAVA API层面的标准,在java体系中,多个client均可以通过JMS进行交互,不需要应用修改代码,但是其对跨平台的支持较差。
- 提供两种消息模型:
①Peer-2-Peer
②Pub/sub
AMQP与JMS对比:
AMQP为消息定义了线路层(wire-level protocol)的协议,而JMS所定义的是API规范。JMS的API协议能够确保所有的实现都能通过通用的API来使用,但是并不能保证某个JMS实现所发送的消息能够被另外不同的JMS实现所使用。而AMQP的线路层协议规范了消息的格式,消息在生产者和消费者间传送的时候会遵循这个格式。这样AMQP在互相协作方面就要优于JMS——它不仅能跨不同的AMQP实现,还能跨语言和平台。
- 相比JMS,AMQP另外一个明显的优势在于它具有更加灵活和透明的消息模型。使用JMS的话,只有两种消息模型可供选择:点对点和发布-订阅。这两种模型在AMQP可以实现,而且AMQP还能够以其他的多种方式来发送消息,这是通过将消息的生产者与存放消息的队列解耦实现的。
- 在JMS中,有三个主要的参与者:消息的生产者、消息的消费者以及在生产者和消费者之间传递消息的通道(队列或主题)。
- 在JMS中,通道有助于解耦消息的生产者和消费者,但是这两者依然会与通道相耦合。生产者会将消息发布到一个特定的队列或主题上,消费者从特定的队列或主题上接收这些消息。通道具有双重责任,也就是传递数据以及确定这些消息该发送到什么地方,队列的话会使用点对点算法发送,主题的话就使用发布-订阅的方式。
AMQP的生产者并不会直接将消息发布到队列中。AMQP在消息的生产者以及传递信息的队列之间引入了一种间接的机制:Exchange。
①消息的生产者将信息发布到一个Exchange。Exchange会绑定到一个或多个队列上,它负责将信息路由到队列上。信息的消费者会从队列中提取数据并进行处理。
②AMQP定义了四种不同类型的Exchange,每一种都有不同的路由算法,这些算法决定了是否要将信息放到队列中。根据Exchange的算法不同,它可能会使用消息的routing key和/或参数,并将其与Exchange和队列之间binding的routing key和参数进行对比。(routing key可以大致理解为Email的收件人地址,指定了预期的接收者。)如果对比结果满足相应的算法,那么消息将会路由到队列上。否则的话,将不会路由到队列上。
③四种标准的AMQP Exchange如下所示:
<1>Direct:如果消息的routing key与binding的routing key直接匹配的话,消息将会路由到该队列上;
<2>Topic:如果消息的routing key与binding的routing key符合通配符匹配的话,消息将会路由到该队列上;
<3>Headers:如果消息参数表中的头信息和值都与bingding参数表中相匹配,消息将会路由到该队列上;
<4>Fanout:不管消息的routing key和参数表的头信息/值是什么,消息将会路由到所有队列上。
JMS与MQ区别:
- JMS:
①JMS即Java消息服务(Java Message Service)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。
②JMS是一种与厂商无关的 API,用来访问消息收发服务(消息中间件)。它类似于JDBC(Java DatabaseConnectivity):这里,JDBC 是可以用来访问许多不同关系数据库的API,而JMS同样提供与厂商无关的访问方式来访问消息收发服务,许多厂商目前都支持JMS,包括 IBM 的 MQSeries、BEA的 Weblogic JMS service和 Progress 的 SonicMQ,这只是几个例子。 JMS 使您能够通过消息收发服务从一个 JMS 客户机向另一个JMS客户机发送消息。消息是 JMS 中的一种类型对象,由两部分组成:报头和消息主体。报头由路由信息以及有关该消息的元数据组成。消息主体则携带着应用程序的数据或有效负载。根据有效负载的类型来划分,可以将消息分为几种类型,它们分别携带:简单文本(TextMessage)、可序列化的对象 (ObjectMessage)、属性集合 (MapMessage)、字节流 (BytesMessage)、原始值流 (StreamMessage),还有无有效负载的消息 (Message)。 - MQ:
①MQ全称为消息队列(Message Queue), MQ是一种应用程序与应用程序之间的通信方法。应用程序通过消息队列来通信,而无需专用连接来链接它们。消息传递指的是程序通过在消息队列中收发数据进行通信,而不是通过直接调用彼此来通信。队列的使用除去了接收和发送应用程序同时执行的要求。其中较为成熟的MQ产品有IBM的WEBSPHERE MQ。 - 二者之间的关系:
①JMS是一个用于提供消息服务的技术规范,它制定了在整个消息服务提供过程中的所有数据结构和交互流程。而MQ则是消息队列服务,是面向消息中间件(MOM)的最终实现,是真正的消息服务提供者。MQ的实现可以基于JMS,也可以基于其他规范或标准,其中ActiveMQ就是基于JMS规范实现的消息队列。
Kafka与JMS:
- Apache Kafka是一个开源消息系统,由Scala写成。是由Apache软件基金会开发的一个开源消息系统项目,目标是为处理实时数据提供一个统一、高通量、低等待的平台,Kafka被广泛地应用于各种流式计算中。
Kafka提供了类JMS的特性,但在设计实现上并不遵循JMS规范,Kafka对消息保存时根据Topic进行归类,发送消息者称为Producer,消息接受者称为Consumer,此外kafka集群有多个kafka实例组成,每个实例(server)称为broker。同时无论是kafka集群,还是producer和consumer都依赖于zookeeper集群保存一些meta信息,来保证系统可用性。
MQ协议
MQ协议简介:
AMQP协议:
①AMQP即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同开发语言等条件的限制。
②优点:可靠、通用- MQTT协议:
①MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通信协议。
②优点:格式简洁、占用带宽小、移动端通信、PUSH、嵌入式系统 - STOMP协议:
①STOMP(Streaming Text Orientated Message Protocol)是流文本定向消息协议,是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议。STOMP提供一个可互操作的连接格式,允许客户端与任意STOMP消息代理(Broker)进行交互。
②优点:命令模式(非topic\\queue模式) - XMPP协议:
①XMPP(可扩展消息处理现场协议,Extensible Messaging and Presence Protocol)是基于可扩展标记语言(XML)的协议,多用于即时消息(IM)以及在线现场探测。适用于服务器之间的准即时操作。核心是基于XML流传输,这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息,即使其操作系统和浏览器不同。
②优点:通用公开、兼容性强、可扩展、安全性高,但XML编码格式占用带宽大 其他基于TCP/IP自定义的协议:
①有些特殊框架(如:redis、kafka、zeroMq等)根据自身需要未严格遵循MQ规范,而是基于TCP\\IP自行封装了一套协议,通过网络socket接口进行传输,实现了MQ的功能。
MQ方案对比
主流mq区别对比:
MQ方案比较:
activemq:
①虽然是java写的消息队列,但是提供Java, C, C++, C#, Ruby, Perl, Python, php各种客户端,所以语言上是没什么问题的。配置和使用,基本上是java xml这一套。同时对jms、spring之类的支持很友好。
②而且因为是Java写的,所以可以作为一个jar包,放到java项目里,用代码启动和配置,这个对于java开发者而言是不是相当爽?毕竟还是有些场景,需要我们把队列放到自己项目内部,随项目启动而启动的。而且,还可以类似拓展tomcat一样,自己写java的plugin来拓展activemq。比如说,我有10万硬件连到mq上,这10万设备每个都有用户名密码,这个时候我们可以用java写个权限验证,从数据库里查这10万用户名密码。
③activemq支持主从复制、集群。但是集群功能看起来很弱,只有failover功能,即我连一个失败了,可以切换到其他的broker上。这一点貌似不太科学。假设有三个broker,其中一个上面没有consumer,但另外两个挂了,消息会转到这个上面来,堆积起来。看样子activemq还在升级中。
④activemq工作模型比较简单。只有两种模式 queue,topics 。
⑤queue就多对一,producer往queue里发送消息,消费者从queue里取,消费一条,就从queue里移除一条。如果一个消费者消费速度不够快怎么办呢?在activemq里,提供messageGroup的概念,一个queue可以有多个消费者,但是他们得标记自己是一个messageGroup里的。这样,消息会轮训发送给每个消费者,也就是说消费者不会重复消费同一条消息。但是每条消息只被消费一次。
⑥topics就是广播。producer往broker发消息,每个消息包含topic。消费者订阅感兴趣的topic,所有订阅了topic的消费者都会收到消息。当然订阅分持久不持久。持久订阅,当消费者断开一会,再连上来,仍然会把没收到的消费发过来。不持久的订阅,断开这段时间的消息就收不到了。
⑦activemq支持mqtt、ssl。rabbitmq:
①rabbitmq用erlang写的。安装完才10m不到,在windows上使用也非常方便,在这点上完爆了activemq,java又臭又长没办法啊。rabbitmq给我感觉更像oracle,功能非常强大。安装完,也有实例的概念,可以像建数据库一样,建实例,建用户划权限。同时监控系统也很好用。这些都是好处,同时也是累赘,整体上来说rabbitmq比activemq复杂太多了。
②从机制上来讲,rabbitmq也有queue和topic的概念,发消息的时候还要指定消息的key,这个key之后会做路由键用。但是多了一个概念叫做交换器exchange。exchange有四种,direct、fanout、topic、header。也就是说,发消息给rabbitmq时,消息要有一个key,并告诉他发给哪个exchange。exchange收到之后,根据key分发或者广播给queue。消费者是从queue里拿消息的,并接触不到交换机。
Kafka:
①Apache下的一个子项目,使用scala实现的一个高性能分布式Publish/Subscribe消息队列系统,具有以下特性:
<1>快速持久化:通过磁盘顺序读写与零拷贝机制,可以在O(1)的系统开销下进行消息持久化;
<2>高吞吐:在一台普通的服务器上既可以达到10W/s的吞吐速率;
<3>高堆积:支持topic下消费者较长时间离线,消息堆积量大;
<4>完全的分布式系统:Broker、Producer、Consumer都原生自动支持分布式,依赖zookeeper自动实现复杂均衡;
<5>支持Hadoop数据并行加载:对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。
②kafka中只有topic,但是每个topic可以有很多partition分区。
上图中kafka集群由两台机器组成。topic被分成四个分区,server1维护p0,p3。 在kafka中,每个消费者都要指出自己属于哪个consumerGroup,每个consumer可以读取多个partition。但是一个partition在同一个consumerGroup中,只会被一个consumer消费。以此保证不会重复消费。而且在一个partition中,消息被消费的顺序是可保障的。上图中,consumer group A 由两个consumer组成,因此一个consumer可以消费两个partition。如果要保证严格的顺序性,那么就要像consumer group B一样,每个consumer只消费一个partition。kafka和rabbitmq及activemq机制上略有区别。rabbitmq和activemq都是消费后就删除消息,没有重复消费的功能,而kafka 队列中的内容按策略存储一定时间,消费者通过指定偏移量来读取数据。如果使用基础api可以从任意位置读取。kafka同时提供高级api,即kafka来维护每个消费者当前读到什么位置了,下次再来,可以接着读。RocketMQ:
①阿里系下开源的一款分布式、队列模型的消息中间件,原名Metaq,3.0版本名称改为RocketMQ,是阿里参照kafka设计思想使用java实现的一套mq。同时将阿里系内部多款mq产品(Notify、metaq)进行整合,只维护核心功能,去除了所有其他运行时依赖,保证核心功能最简化,在此基础上配合阿里上述其他开源产品实现不同场景下mq的架构,目前主要多用于订单交易系统。
②具有以下特点:
<1>能够保证严格的消息顺序
<2>提供针对消息的过滤功能
<3>提供丰富的消息拉取模式
<4>高效的订阅者水平扩展能力
<5>实时的消息订阅机制
<6>亿级消息堆积能力总体而言:
①我感觉kafka安装使用最简单,同时如果有集群要求,那么kafka是当仁不让的首选。尤其在海量数据,以及数据有倾斜问题的场景里,因为partition的缘故,数据倾斜问题自动解决。比如个别Topic的消息量非常大,在kafka里,调整partition数就好了。反而在rabbitmq或者activemq里,这个不好解决。
②rabbitmq是功能最丰富,最完善的企业级队列。基本没有做不了的,就算是做类似kafka的高可用集群,也是没问题的,不过安装部署麻烦了点。
③activemq相对来说,显的老套了一些。不过毕竟是java写的,在内嵌到项目中的情况下,或者是简单场景下,还是不错的选择。- 链接:activemq、rabbitmq、kafka原理和比较
以上是关于消息中间件MQ知识概括的主要内容,如果未能解决你的问题,请参考以下文章