消息队列简介

一:为何会有消息队列

咱们来看看下面遇到的几种业务场景
1)好比咱们在一些高并发环境下,来不及同步处理数据,请求每每就会发生阻塞。好比往mysql数据中大量的插入数据,那么mysql可能由于量大一时处理不过来,致使锁表。 这时候就能够借助队列来异步处理。
也就是说,在系统中出现 “生成” 和 “消费” 的速度或者稳定性因素不一致的时候,就须要消息队列,来弥合双方的差别。php

2)有些业务不须要当即处理消息,而是能够放到后面来进行处理。好比咱们注册的时候须要发送邮件,注册了后就能够把须要发送邮件的消息投递到消息队列,让其余程序来单独的处理发送邮件的任务。java

3)好比说web用的是php,后端处理语言用的java,这种使用不一样的语言,也可使用消息队列mysql

4)还有一些任务系统,能够先把用户发起的任务请求接收过来发到消息队列中,而后后端就能够开启多个程序来消费处理任务web

二:消息队列使用的场景

1)过载保护
在访问量剧增的状况下,应用仍然须要继续发挥做用,可是这样的突发流量没法提取预知;若是觉得了能处理这类瞬间峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列可以使关键组件顶住突发的访问压力,而不会由于突发的超负荷的请求而彻底崩溃。还能够用做错峰与流控
2)异步通讯
有些业务不想也不须要当即处理消息。消息队列提供了异步处理机制,容许用户把一个消息放入队列,但并不当即处理它。想向队列中放入多少消息就放多少,而后在须要的时候再去处理它们。
3)解耦
下降工程间的强依赖程度,针对异构系统进行适配。在项目启动之初来预测未来项目会碰到什么需求,是极其困难的。经过消息系统在处理过程当中间插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口,当应用发生变化时,能够独立的扩展或修改两边的处理过程,只要确保它们遵照一样的接口约束。
4)扩展性
由于消息队列解耦了你的处理过程,因此增大消息入队和处理的频率是很容易的,只要另外增长处理过程便可。不须要改变代码、不须要调节参数。便于分布式扩容。
5)冗余
有些状况下,处理数据的过程会失败。除非数据被持久化,不然将形成丢失。消息队列把数据进行持久化直到它们已经被彻底处理,经过这一方式规避了数据丢失风险。许多消息队列所采用的"插入-获取-删除"范式中,在把一个消息从队列中删除以前,须要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕
6)可恢复性
系统的一部分组件失效时,不会影响到整个系统。消息队列下降了进程间的耦合度,因此即便一个处理消息的进程挂掉,加入队列中的消息仍然能够在系统恢复后被处理。
7)顺序保证
在大多使用场景下,数据处理的顺序都很重要。大部分消息队列原本就是排序的,而且能保证数据会按照特定的顺序来处理
8)缓冲
在任何重要的系统中,都会有须要不一样的处理时间的元素。消息队列经过一个缓冲层来帮助任务最高效率的执行,该缓冲有助于控制和优化数据流通过系统的速度。以调节系统响应时间
9)数据流处理
分布式系统产生的海量数据流,如:业务日志、监控数据、用户行为等,针对这些数据流进行实时或批量采集汇总,而后进行大数据分析是当前互联网的必备技术,经过消息队列完成此类数据收集是最好的选择
10)最终一致性
最终一致性指的是两个系统的状态保持一致,要么都成功,要么都失败。固然有个时间限制,理论上越快越好,但实际上在各类异常的状况下,可能会有必定延迟达到最终一致状态,但最后两个系统的状态是同样的。
业界有一些为“最终一致性”而生的消息队列,如Notify(阿里)、QMQ(去哪儿)等,其设计初衷,就是为了交易系统中的高可靠通知。sql

三: 消息队列消息模型

message channel模型后端

消息通道做为在客户端(消费者,Consumer)与服务(生产者,Producer)之间引入的间接层,能够有效地解除两者之间的耦合。只要实现规定双方须要通讯的消息格式,以及处理消息的机制与时机,就能够作到消费者对生产者的“无知”。事实上,该模式能够支持多个生产者与消费者。例如,咱们可让多个生产者向消息通道发送消息,由于消费者对生产者的无知性,它没必要考虑到底是哪一个生产者发来的消息安全

发布者-订阅者(Publisher-Subscriber)模式
一旦消息通道须要支持多个消费者时,就可能面临两种模型的选择:拉模型与推模型。拉模型是由消息的消费者发起的,主动权把握在消费者手中,它会根据本身的状况对生产者发起调用
a) 拉模型
拉模型的另外一种体现则由生产者在状态发生变动时,通知消费者其状态发生了改变。但获得通知的消费者却会以回调方式,经过调用传递过来的消费者对象获取更多细节消息服务器

b)推模型
推模型的主动权经常掌握在生产者手中,消费者被动地等待生产者发出的通知,这就要求生产者必须了解消费者的相关信息
对于推模型而言,消费者无需了解生产者。在生产者通知消费者时,传递的每每是消息(或事件),而非生产者自身。同时,生产者还能够根据不一样的状况,注册不一样的消费者,又或者在封装的通知逻辑中,根据不一样的状态变化,通知不一样的消费者并发

两种模型各有优点。拉模型的好处在于能够进一步解除消费者对通道的依赖,经过后台任务去按期访问消息通道。坏处是须要引入一个单独的服务进程,以Schedule形式执行。而对于推模型而言,消息通道事实上会做为消费者观察的主体,一旦发现消息进入,就会通知消费者执行对消息的处理。不管推模型,拉模型,对于消息对象而言,均可能采用相似Observer模式的机制,实现消费者对生产者的订阅,所以这种机制一般又被称为Publisher-Subscriber模式异步


消息路由(Message Router)模式
不管是Message Channel模式,仍是Publisher-Subscriber模式,队列在其中都扮演了举足轻重的角色。然而,在企业应用系统中,当系统变得愈来愈复杂时,对性能的要求也会愈来愈高,此时对于系统而言,可能就须要支持同时部署多个队列,并可能要求分布式部署不一样的队列。

四:通常消息队列要素组成

Broker:消息服务器,做为server提供消息核心服务
Producer:消息生产者,业务的发起方,负责生产消息传输给broker,
Consumer:消息消费者,业务的处理方,负责从broker获取消息并进行业务逻辑处理
Topic:主题,发布订阅模式下的消息统一聚集地,不一样生产者向topic发送消息,由MQ服务器分发到不一样的订阅者,实现消息的广播
Queue:队列,PTP模式下,特定生产者向特定queue发送消息,消费者订阅特定的queue完成指定消息的接收
Message:消息体,根据不一样通讯协议定义的固定格式进行编码的数据包,来封装业务数据,实现消息的传输

参考:http://www.infoq.com/cn/articles/message-based-distributed-architecture