##背景
之前做日志收集模块时,用到flume,另外也有的方案,集成kafaka来提升系统可扩展性,其中涉及到消息队列
,当时自己并不清楚为什么要使用消息队列
,而在我自己提出的原始日志采集方案中不适用消息队列
时,有几个基本问题:1.日志文件上传过程,有个基本的生产者-消费者
问题;2.另外系统崩溃时,数据丢失的处理问题。
今天,几位同事再次谈到消息队列
这么个东西,很NB的样子,我也想弄清楚,OK,搞起。
##什么是消息队列
消息队列(Message Queue,简称MQ),从字面意思上看,本质是个队列,FIFO先入先出,只不过队列中存放的内容是message
而已。其主要用途:不同进程Process/线程Thread之间通信。为什么会产生消息队列
?这个问题问的好,我大概查了一下,没有查到最初产生消息队列的背景,但我猜测可能几个原因:
- 不同进程(process)之间传递消息时,两个进程之间耦合程度过高,改动一个进程,引发必须修改另一个进程,为了隔离这两个进程,在两进程间抽离出一层(一个模块),所有两进程之间传递的消息,都必须通过
消息队列
来传递,单独修改某一个进程,不会影响另一个; - 不同进程(process)之间传递消息时,为了实现标准化,将消息的格式规范化了,并且,某一个进程接受的消息太多,一下子无法处理完,并且也有先后顺序,必须对收到的消息进行排队,因此诞生了事实上的
消息队列
;
不管到底是什么原因催生了消息队列
,总之,上面两个猜测是其实际应用的典型场景。
##为什么要用
切合前一部分猜测的消息队列
产生背景,其主要解决两个问题:
- 系统解耦:项目开始时,无法确定最终需求,不同进程间,添加一层,实现解耦,方便今后的扩展。
- 消息缓存:系统中,不同进程处理消息速度不同,MQ,可以实现不同Process之间的缓冲,即,写入MQ的速度可以尽可能地快,而处理消息的速度可以适当调整(或快、或慢)。
下面针对系统解耦、消息缓存两点,来分析实际应用消息队列
过程中,可能遇到的问题。虚拟场景:Process_A通过消息队列MQ_1向Process_B传递消息,几个问题:
- 针对MQ_1中一条消息message_1,如何确保Process_B从MQ_1中只取一次message_1,不会重复多次取出message_1?
- 如果MQ_1中message_1已经被Process_B取出,正在处理的关键时刻,Process_B崩溃了,哭啊,我的问题是,如果重启Process_B,是否会丢失message_1?
不要着急,阅读了下面的简要介绍后,水到渠成,上面几个问题就可以解决了。 消息队列有如下几个好处,这大都是由其系统解耦和消息缓存两点扩展而来的:
- 提升系统可靠性:
- 冗余:Process_B崩溃之后,数据并不会丢失,因为MQ多采用
put-get-delete
模式,即,仅当确认message被完成处理之后,才从MQ中移除message; - 可恢复:MQ实现解耦,部分进程崩溃,不会拖累整个系统瘫痪,例,Process_B崩溃之后,Process_A仍可向MQ中添加message,并等待Process_B恢复;
- 可伸缩:有较强的峰值处理能力,通常应用会有突发的访问流量上升情况,使用足够的硬件资源时刻待命,空闲时刻较长,资源浪费,而
消息队列
却能够平滑峰值流量,缓解系统组件的峰值压力;
- 冗余:Process_B崩溃之后,数据并不会丢失,因为MQ多采用
- 提升系统可扩展性:
- 调整模块:由于实现解耦,可以很容易调整,消息入队速率、消息处理速率、增加新的Process;
- 其他:
- 单次送达:保证MQ中一个message被处理一次,并且只被处理一次,本质:get获取一个message后,这一message即被预定,同一进程不会再次获取这一message,当且仅当进程处理完这一message后,MQ中会delete这个message,否则,过一段时间后,这一message自动解除被预订状态,进程能够重新预定这个message;
- 排序保证:即,满足队列的FIFO,先入先出策略;
- 异步通信:很多场景下,不会立即处理消息,这是,可以在MQ中存储message,并在某一时刻再进行处理;
- 数据流的阶段性能定位:获取用户某一操作的各个阶段(通过message来标识),捕获不同阶段的耗时,可用于定位系统瓶颈。
##常用的消息队列
(doing…)
##小结
消息队列
实现了进程间通信的升级,如下图所示:
##参考来源
- top 10 uses for message queue:英文原文、pdf版本、中文译文
- Message Queue wiki
- http://bbs.csdn.net/topics/110160741
- http://www.cnblogs.com/yuanyi_wang/archive/2009/12/30/1636178.html
- http://www.php1.cn/article/9865.html
相关推荐
进程间通信之消息队列 ( message queue ) 消息队列是消息的链表,具有特定的格式,并由消息队列标识符标识. 七种进程间通信方式: 一.无名管道( pipe ) 二.有名管道( fifo ) 三.共享内存 ( shared memory ) 四....
此文档是C#开发的消息队列系统,适用于消息队列入门与新手。 在Windows 7 上安装消息队列的步骤 打开“控制面板”。 单击“程序”,然后在“程序和功能”下, 单击“打开或关闭 Windows 功能”。 -或者-单击“经典...
spring-redis-mq, 基于 Spring 和 Redis 的分布式消息队列(MessageQueue)实现
整个延迟队列由4个部分组成: 1. JobPool用来存放所有Job的元信息。 2. DelayBucket是一组以时间为维度的有序队列,用来存放所有需要延迟的Job(这里只存放Job Id)。 3. Timer负责实时扫描各个Bucket,并将delay...
消息队列 Queue与Topic区别
http://127.0.0.1:8000/getList queueName">一个NodeJS和redis做的基于http协议使用的队列 做了点小修改 支持多个队列和post提交 原github地址:https://github.com/lnmp/nodemq 使用方法: 在安装好redis和nodejs...
“消息队列”是 Microsoft 的消息处理技术,它在任何安装了 Microsoft Windows 的计算机组合中,为任何应用程序提供消息处理和消息队列功能,无论这些计算机是否在同一个网络上或者是否同时联机。 “消息队列网络”...
1. Message Queue的角色 在你的Android程序里,新诞生一个线程,或称执行(Thread)时,并不会自动建立其Message Loop。 Android里并没有Global的Message Queue数据结构,例如,不同APK里的对象不能透过...
redis 流的消息队列。 支持 Redis >= 5.0.0 和 (Node.js >= 8)。快速开始安装$ npm install redis-queue-stream基本用法 const redisQueue = require ( 'redis-queue-stream' ) ;const RedisQ = new redisQueue ( ...
Unity3d 队列 方法 Queue
tp5.1安装使用think-queue,处理任务,在readme.md文件里有详细的步骤
延迟队列, 参考有赞延迟队列设计实现
php队列+php-redis队列+php-redis扩展,php入队出队,redis入队出队以及其php .dll扩展
详细描述了Android的消息处理机制,Message和MessageQueue类的详解
消息的类型,在Handler类中的handleMessage方法中得到单个的消息进行处理,在单线程模型下,为了线程通信问题,Android设计了一个Message Queue(消息队列), 线程间可以通过该Message Queue并结合Handler和Looper组件...
Redis通常用作消息传递服务器,以实现对后台作业或其他类型的消息传递任务的处理。 它实现了此处描述的可靠队列模式: ://redis.io/commands/rpoplpush。 安装 $ gem install redis-queue 测验 $ bundle install ...
MessageQueue实战MessageQueue实战MessageQueue实战MessageQueue实战MessageQueue实战MessageQueue实战MessageQueue实战MessageQueue实战MessageQueue实战MessageQueue实战
本文实例讲述了PHP实现基于Redis的MessageQueue队列封装操作。分享给大家供大家参考,具体如下: Redis的链表List可以用来做链表,高并发的特性非常适合做分布式的并行消息传递。 项目地址:...
主要介绍了Python高级编程之消息队列(Queue)与进程池(Pool),结合实例形式详细分析了Python消息队列与进程池的相关原理、使用技巧与操作注意事项,需要的朋友可以参考下
c++消息队列queue.rar