概述
消息队列比作一个存放消息的容器,需要使用消息的时候可以取出消息供自己使用。是分布式中重要的组件,使用消息队列主要是为了通过异步处理提高系统性能和削锋、降低系统耦合性。(注意消费信息顺序问题,可能出现消费失败,或者一个queue多个consumer也会导致消息被消费顺序不对,一定要保证消息被消费的顺序正确)。
功能(优点)
通过异步处理提高系统性能
(削峰、减少响应所需时间)
用户的请求数据发给消息队列之后,立即返回给客户端,然后服务端从消息队列中获取消息异步写入数据库。对比串行的服务,可以提高响应速度。
降低系统耦合性
消息队列使用发布-订阅模式,生产者发送消息,一个或者多个消费者订阅消息。可知,消费者和生产者之间没有直接的耦合,彼此直接并不知道是谁调用和产生的。对于新增的业务,只要对该消息感兴趣,就可以订阅,对原有的系统并没有影响。
限流削峰
广泛用于秒杀和抢购的活动中,避免流量过大导致应用系统挂掉。(短时间将高并发的事务储存到消息队列中,削平高峰期的并发事务。)
消息系统驱动
系统分为消息队列、消息生产者、消息消费者。
缺点
系统可用性降低
在加入MQ之前,不用考虑消息丢失、MQ挂掉等问题,加入了之后会有这样的问题,因此可用性降低。
系统复杂度提高
需要保证消息没有被重复消费、处理消失丢失的情况、保证消息传递的顺序等等。
一致性问题
消息队列可以实现异步,提高响应速度,但是如果消息的真正消费者没有正确消费,就会导致数据不一致的问题。(比如用户提交订单后,应该返回的是订单提交成功,到最后订单处理完毕、甚至出库了才通过邮件或者短信通知。例如:火车票和电影票)
PS
为了避免消息队列服务器的宕机,生产者会将发送出去的消息储存在服务器中,等到消息真正被消费了,才删除消息。消息队列宕机之后,生产者服务器会选择分布式消息队列服务器集群中的其他服务器发布消息。
JMS VS AMQP
JMS JavaMessageService
Java消息服务,JMS的客户端之间可以通过JMS服务进行异步的消息传输,JMS API 是一个消息服务的标准或者说规范,允许应用程序组件基于JavaEE平台创建、发送、接收和读取消息。ActiveMQ就是基于JMS规范实现的
JMS两种模型
点到点(p2p)
queue作为消息通信的载体;满足生产者和消费者的模式,一条消息只能被一个消费者使用,未被消费的消息在队列中保留到被消费或者超时。
发布订阅模型
topic作为消息通信的载体,类似于广播模式,发布一条消息,该消息通过主题传递给所有的订阅者。在一条消息广播之后才订阅的用户是收不到该条信息的。
JMS五种不同的消息正文格式
JMS定义了五种不同的消息正文格式,以及调用的消息类型,允许发送并接收以一些不同的数据格式,提供现有消息格式的一些级别的兼容性。
StreamMessage -- Java原始值的数据流
MapMessage--一套名称-值对
TextMessage 一个字符串对象
ObjectMessage -一个序列化的 Java对象
ByteMessage 一个字节的数据流
AMQP
AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准 高级消息队列协议(二进制应用层协议),是应用层协议的一个开放标准,为面向消息的中间件设计,兼容 JMS。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件同产品,不同的开发语言等条件的限制。
RabbitMQ 就是基于 AMQP 协议实现的。
对比
总结:
AMQP 为消息定义了线路层(wire-level protocol)的协议,而JMS所定义的是API规范。在 Java 体系中,多个client均可以通过JMS进行交互,不需要应用修改代码,但是其对跨平台的支持较差。而AMQP天然具有跨平台、跨语言特性。
JMS 支持TextMessage、MapMessage 等复杂的消息类型;而 AMQP 仅支持 byte[] 消息类型(复杂的类型可序列化后发送)。
由于Exchange 提供的路由算法,AMQP可以提供多样化的路由方式来传递消息到消息队列,而 JMS 仅支持 队 列 和 主题/订阅 方式两种。
常见的消息队列对比
总结:
ActiveMQ 的社区算是比较成熟,但是较目前来说,ActiveMQ 的性能比较差,而且版本迭代很慢,不推荐使用。
RabbitMQ 在吞吐量方面虽然稍逊于 Kafka 和 RocketMQ ,但是由于它基于 erlang 开发,所以并发能力很强,性能极其好,延时很低,达到微秒级。但是也因为 RabbitMQ 基于 erlang 开发,所以国内很少有公司有实力做erlang源码级别的研究和定制。如果业务场景对并发量要求不是太高(十万级、百万级),那这四种消息队列中,RabbitMQ 一定是你的首选。如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。
RocketMQ 阿里出品,Java 系开源项目,源代码我们可以直接阅读,然后可以定制自己公司的MQ,并且RocketMQ 有阿里巴巴的实际业务场景的实战考验。RocketMQ 社区活跃度相对较为一般,不过也还可以,文档相对来说简单一些,然后接口这块不是按照标准 JMS 规范走的有些系统要迁移需要修改大量代码。还有就是阿里出台的技术,你得做好这个技术万一被抛弃,社区黄掉的风险,那如果你们公司有技术实力我觉得用RocketMQ 挺好的
kafka 的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms 级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展。同时 kafka 最好是支撑较少的 topic 数量即可,保证其超高吞吐量。kafka 唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略这个特性天然适合大数据实时计算以及日志收集。