为什么用消息队列
举例
比如在一个企业里,技术老大接到boss的任务,技术老大把这个任务拆分成多个小任务,完成所有的小任务就算搞定整个任务了。
那么在执行这些小任务的时候,可能有一个环节很费时间,并且优先级很低,推迟完成也不影响整个任务运转,那么技术老大就会将这个很费时间,且不重要的任务,丢给他的小弟去解决,自己继续完成其他任务。
转化为计算机思想
那个技术老大就是一个 程序系统,那个小弟就是消息队列。
当程序系统发现某些任务耗费时间且优先级较低,迟点完成也不影响整个任务,就把这个任务丢给消息队列。
场景
在程序系统中,例如外卖系统,订单系统,库存系统,优先级较高
发红包,发邮件,发短信,app消息推送等任务优先级很低,很适合交给消息队列去处理,以便于程序系统更快的处理其他请求。
消息队列工作流程
消息队列一般有三个角色:
队列服务端
队列生产者
队列消费者
消息队列工作流程就如同一个流水线,有产品加工,一个输送带,一个打包产品
输送带就是 不停运转的消息队列服务端
加工产品的就是 队列生产者
在传输带结尾打包产品的 就是队列消费者
队列产品
RabbitMQ
Erlang编写的消息队列产品,企业级消息队列软件,支持消息负载均衡,数据持久化等。
ZeroMQ
saltstack软件使用此消息,速度最快。
Redis
key-value的系统,也支持队列数据结构,轻量级消息队列
Kafka
由Scala编写,目标是为处理实时数据提供一个统一、高通量、低等待的平台
一个app系统消息队列工作流程
消费者,一个后台进程,不断的去检测消息队列中是否有消息,有消息就取走,开启新线程去处理业务,如果没有一会再来
在流式计算中,Kafka一般用来缓存数据,Storm通过消费Kafka的数据进行计算。
1)Apache Kafka是一个开源消息系统,由Scala写成。是由Apache软件基金会开发的一个开源消息系统项目。
2)Kafka最初是由LinkedIn公司开发,并于 2011年初开源。2012年10月从Apache Incubator毕业。该项目的目标是为处理实时数据提供一个统一、高通量、低等待的平台。
3)Kafka是一个分布式消息队列。Kafka对消息保存时根据Topic进行归类,发送消息者称为Producer,消息接受者称为Consumer,此外kafka集群有多个kafka实例组成,每个实例(server)成为broker。
4)无论是kafka集群,还是producer和consumer都依赖于zookeeper集群保存一些meta信息,来保证系统可用性。
点对点模式(一对一,消费者主动拉取数据,轮询机制,消息收到后消息清除,ack确认机制)
点对点模型通常是一个基于拉取
或者轮询
的消息传送模型,这种模型从队列中请求信息,而不是将消息推送到客户端。
这个模型的特点是发送到队列的消息被一个且只有一个接收者接收处理,即使有多个消息监听者也是如此。
发布/订阅模式(一对多,数据生产后,推送给所有订阅者)
发布订阅模型则是一个基于推送的消息传送模型。
发布订阅模型可以有多种不同的订阅者,临时订阅者只在主动监听主题时才接收消息,而持久订阅者则监听主题的所有消息,即使当前订阅者不可用,处于离线状态。
1)程序解耦
允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。
2)冗余:
消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。
许多消息队列所采用的"插入-获取-删除"范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。
3)峰值处理能力:
(大白话,就是本来公司业务只需要5台机器,但是临时的秒杀活动,5台机器肯定受不了这个压力,我们又不可能将整体服务器架构提升到10台,那在秒杀活动后,机器不就浪费了吗?因此引入消息队列)
在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见。
如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。
使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。
4)可恢复性:
系统的一部分组件失效时,不会影响到整个系统。
消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
5)顺序保证:
在大多使用场景下,数据处理的顺序都很重要。
大部分消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。(Kafka保证一个Partition内的消息的有序性)
6)缓冲:
有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情况。
7)异步通信:
很多时候,用户不想也不需要立即处理消息。比如发红包,发短信等流程。
消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。
应用
微信公众号的订阅
生产者写入消息 -> kafka -> 消费者
zookeeper会产生大量网络io,zk所在节点,注意网络监控
kafka角色
编辑, 生产消息,生产者
kafka集群,临时缓存消息 queue队列有kafka维护
消费者 定时/轮训 方式去pull 消息
topic主题
同样的消息类型,放入同一个topic,
例如微信有很多公众号,这个类别在kafka里就叫topic主题
一个消费者可以订阅多个主题