`

消息队列的定义,以及引入消息队列可解决的问题

 
阅读更多

消息队列的定义,以及引入消息队列可解决的问题

 

1. 消息队列中的“消息”即指同一台计算机的进程间,或不同计算机的进程间传送的数据;
“消息队列”是在消息的传输过程中保存消息的容器。
消息被发送到队列中,消息队列充当中间人,将消息从它的源中继到它的目标。

2. 传统的进程通信模式如图1左所示:client调用service,等待service的响应。但是这种模式有很多弊端:
-网络情况不好时,client到Service的调用可能会丢失;
-或者service如果处理时间较长,那么client需要一直hold,甚至调用超时而失败;
-或者service的些许改动会带来client的代码修改等等。

3. 引入消息队列则可以避免这种传统模式的弊端,如图1右所示:
CQM_1.png

 

       图1(左) 典型的Invoke/Respond模型                                 图1(右) 典型的消息队列处理流程

 

4. 消息队列可以带来如下好处:
(1)保证消息的传递。
如果发送消息时接收者不可用,消息队列会保留消息,直到成功地传递它;

(2)提供异步的通信协议。
消息的发送者将消息发送到消息队列后可以立即返回,不用等待接收者的响应,消息会被保存在队列中,直到接收者取出它;

(3)解耦,降低两个进程间的耦合度。
只要消息格式不变,即使接收者的接口、位置、或者配置改变,也不会给发送者带来任何改变;
而且,消息发送者无需知道消息接收者是谁,使得系统设计更清晰;
相反的,例如,远程过程调用(RPC)或者服务间通过socket建立连接,如果对方接口改变了或者对方ip、端口改变了,那么另一方需要改写代码或者改写配置;

(4)提供路由。
发送者无需与接收者建立连接,双方通过消息队列保证消息能够从发送者路由到接收者,甚至对于本来相互网络不通的两个服务,也可以提供消息路由。

为什么需要分布式消息队列

 

可靠
分布式消息队列提供更好的可靠性,主要体现在:
1. 消息会被持久化到分布式存储中。这样避免了单台机器存储的消息由于机器问题导致消息的丢失;
2. 不佳的网络环境中,保证只有当消息的接收者确实收到消息时才从队列中删除消息。

可扩展
可扩展性体现在访问量和数据量两个方面:
访问量:分布式消息队列服务,会随着访问量的增减而自动增减逻辑处理服务器;
数据量:当数据量扩大时,后端分布式存储会自动扩容。

安全
安全体现在以下两个方面:
1. 同时使用消息队列的业务之间不会互相干扰
如果有多个业务同时在使用消息队列,对于单机的消息队列服务,一个业务的消息操作可能会影响其他业务的正常运行。
比如,一个业务的消息操作特别频繁,占据了消息队列的绝大部分服务时间,也占据了这台服务器的绝大部分网络IO,导致其他业务无法正常地与消息队列通信。
而且甚至可能由于服务控制不当,导致机器崩溃,服务停止,业务也跟着停止。
分布式消息队列则不会出现这个问题:
(1)监控措施完善,系统性能指数会控制在一定范围之内,而且有任何异常也会报警;
(2)当访问量和数据量增大时,分布式消息队列服务可以自动扩展。

2. 各业务的消息内容是安全存储的,其他业务不能访问到非自身业务的数据。
一方面是业务需要密钥来访问消息队列;另一方面,消息是被加密存储的。

简单实用
简单实用体现在:
1.透明:接收者和发送者无需知道具体的消息队列的服务器地址,服务器的增减对接收者和发送者透明。
2. 实用:对于两个服务之间不能通信的网络情况,消息队列为他们提供了恰到好处的桥梁。

CMQ的特性

 

消息队列中的“消息”即指同一台计算机的进程间,或不同计算机的进程间传送的数据;“消息队列”是在消息的传输过程中保存消息的容器。
消息被发送到队列中,消息队列充当中间人,将消息从它的源中继到它的目标。

腾讯云计算平台提供的分布式消息队列CMQ服务实现了消息队列的全部宗旨:
1. 保证消息的传递;
2. 提供异步的通信协议;
3. 解耦;
4. 提供路由。

同时,CMQ具有分布式消息队列的全部优势:安全、可靠、简单易用、透明、实用、可扩展,弥补了消息队列潜在的不足,以自己的方式提供更可靠、更安全、更易用、更实用的周到服务。

引入消息队列则可以避免传统进程通信模式的弊端,如下图所示:
CQM_1.png

 

       图1(左) 典型的Invoke/Respond模型                                 图1(右) 典型的消息队列处理流程

CMQ的优势

 

更可靠
(1)接收者接收消息后,CMQ服务并不立刻从队列中删除该消息,只有在接收者确认接到消息,主动发送删除消息请求时,才把消息删除;
(2)保证消息只被接收一次。实现方式是在消息被接收后锁住该条消息,锁有时效,当接收者在时效内没有来删除这条消息,则说明接收者出现异常,锁失效,该条消息可以被再次接收;
(3)应用发送消息,如果直接通过http协议访问消息队列,则消息必须经过base64编码,这样避免了消息的编码格式混乱造成的消息接收错误;CMQ SDK内部进行了base64编码的封装,应用可以传任意内容给SDK接口。

更安全
(1)应用必须登录开放平台,有自己的应用(即具有appid)才可以开通消息队列服务;
(2)开通消息队列时,会告诉用户一个AccessKey作为访问消息队列的密码,之后应用发送和接收消息都要使用该AccessKey;
(3)发送和接收消息时,除了使用AccessKey还要传入应用的appid,而且必须匹配;
(4)应用没有途径可以直接看到其他应用的消息内容。

更易用
(1)只需一键即可开通消息队列服务,只需一键即可创建、删除队列,不用按键即可查看应用已经创建的队列列表及信息。
(2)用户在可视化界面中创建队列后,只需通过http请求访问消息队列。
(3)接口简单,无需对复杂的网络环境进行处理和容错。

更实用
(1)切实解决开放平台中两个应用之间,甚至一个应用内部通信的复杂性。
云平台中各服务所在服务器地址不确定,所以服务需要比较复杂的配置才能通信,或者无法通信。但是应用可以轻松访问CMQ服务;
(2)访问速度快。
消息队列以其特有的设计方案,实现了单次请求响应快、高并发的特性。
平均单次请求10ms,支持单队列200次/每秒的访问量,单应用2万次/秒甚至更高(支持更高只需扩展服务器而已)的访问量。

CMQ适用的场景

 

异步通信
对于BS(Browser-Server 浏览器)架构,很多情景下server的处理时间较长。
如果浏览器发送请求后,保持跟server的连接,等待server响应,那么一方面会对用户的体验有负面影响;
另一方面,很有可能会由于超时,提示用户服务请求失败。

对于这种情景,消息队列提供了一个较好的解决方案,如图2所示:
CQM_3.png

 

                              图2 BS通信模型的优化方案

 

工作流程如下:
(1)浏览器向服务器发送请求后,服务器接到响应后立即返回;
(2)之后,服务器向消息队列发送已经完成的结果信息;
(3)浏览器端用js等技术循环请求该消息队列,检查是否有新的结果信息,如果有则获取消息,并将结果渲染到浏览器界面上。


命令下发/分布式处理模型
在分布式的应用系统中,经常会有master-worker的模型(Map-Reduce就是一个典型的例子)。
有任务到达时,master会将任务直接分配给worker或者切成子任务分配给worker,但是有一个原则就是一个任务或者子任务只希望被一个worker执行。

传统的处理方式是:
(1)master要维护worker的心跳,知道有哪些worker可以接受任务,然后master挑选一个worker,与其建立连接,并发送数据包(即命令);
(2)worker收到数据包(命令)后,如果能够正常解析并执行,则反馈master;
(3)如果worker许久没有反馈,则master会做一系列工作,包括check该worker状态、确保死掉了之后再挑选一个worker分配任务。

这样的处理方式对master压力过大,也过于复杂。使用消息队列则可对master和worker进行有效解耦,如图3所示:
CQM_4.png

 

                            图3 master-worker命令下发模型的优化方案

 

CMQ中,master和worker的配置中都事先配置好两个队列名:1任务下发队列名,结果反馈队列名。
master有任务下发时,就向该“任务下发”队列中发送消息;
worker定期检查“任务下发”队列,发现队列有消息则获取(因为CMQ的特性保证了一条消息只会被一个接收者接收,所以一个任务只会被一个worker执行)。
之后worker执行的结果都发送到“结果反馈”队列中,master定期检查“结果反馈”队列,汇总执行结果。
所有这种一对多的通信,并且只希望这个“多”中只有一个真正接收到消息,则都可采用上述的解决方案。


数据上报模型
凡是多对一的通信都可以采用CMQ来解耦合,如下面例子所示:
1. 上文“命令下发/分布式处理模型”中给出的master-worker模型解决方案中,多个worker向同一个队列发送消息,master从该队列接收消息,就是一个典型的数据上报模型,即图3中的结果反馈的过程。

2. 监控服务中各个机器有后台进程定期汇报机器状态,中心服务收集各机器状态,进行计算和统计。也是一个典型的数据上报模型。
监控服务的后台进程可以将状态汇报到一个消息队列,中心服务从这个队列中接收消息,如图4所示:
CQM_5.png

 

                                图4 数据上报模型的优化方案

	

3. 在线游戏中,需要一个可以实时显示当前各团队比赛战况的界面,或者任何需要汇总信息的需求。
这些都可以从各个机器汇报状态到消息队列,汇总服务从队列获取数据、处理数据并显示。

分享到:
评论

相关推荐

    基于通用消息的持久化消息队列设计 (2010年)

    通用消息就是这样的一种中间件,为了改进它的服务质量,本文充分利用了其寻址和通信优势,引入队列和持久化思想,设计了一种消息持久化队列Ebupt Message Queue(EMQ).在实际应用中,EMQ可为上层提供更加可靠的通信...

    ThinkPHP3.2 集成 php-resque: PHP Resque Worker

    注意要定义应用目录,之前发的内容没定义应用目录导致部分小伙伴引发了找不到Queue类的异常 ### 在项目根目录中创建resque入口脚本 ### #!/usr/bin/env php <?php ini_set('display_errors', true); error_...

    django-rq-mail:使用等待和活动队列存储邮件并异步发送

    django-rq-mail 此项目不再维护,它不支持来自 rq 的最新更改 django-rq-mail 是一个基于的简单 Python 库,用于存储发送的电子邮件,并在后台与工作人员... 当一个作业在每个步骤上都经过测试后,我们重新引入的默认

    Python并行分布式框架Celery详解

    在 Python 中定义 Celery 的时候,我们要引入 Broker,中文翻译过来就是“中间人”的意思,在这里 Broker 起到一个中间人的角色。在工头提出任务的时候,把所有的任务放到 Broker 里面,在 Broker 的另外一头,一群...

    Activiti6.0.0最新源码

    作业执行器通过消息队列的方式进行,关于这一点可以参考随后的文章。 瞬态变量的引入。瞬态变量不会存储到 Activiti 变量表中,但仍为单一的事务持续时间执行。比如可以在REST服务之间进行调用的时候使用,或者使用...

    基于最新的Java 21和SpringBoot 3.2 根据eladmin项目进行改造+源代码+文档说明

    - 整合消息队列RabbitMQ,实现消息通知、延迟消息,服务解耦。 - 各模块独立,基本可插拔:若只需查询注解等基础功能,只需引入Core模块即可,Beans, Security, Logging, 3rd Tools, Code Gen 模块可插拔, 除了...

    C#基于异步事件回调多线程容器

    多线程应该采用消息中心来交换数据,这样就规避了线程同步交互,等待,阻塞等等,全部是异步调用,全部是接收消息工作,然后产生消息,线程间没有耦合,消息中心有很多成熟的方案如RabbitMQ, Redis(里面有简单的...

    springCloud

    AMQP,即Advanced message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。 ...

    数据结构习题答案(全部算法)严蔚敏版

    3.2.1 队列的定义及运算 3.2.2 队列的顺序存储结构(向量) 3.2.3 队列的链表存储结构 3.3 栈和队列的算法实现举例 习题三 第4章 串 4.1 串的基本概念 4.2 串的存储结构 4.2.1 串的顺序存储 4.2.2 串的链表...

    操作系统概念归纳总结

    13. 高级通信机制有:共享存储器系统、消息传递系统、管道通信系统。 14. 线程的定义:线程是进程内的一个实体,是处理机调度的基本单位,是程序内部一个单一的顺序控 制流。 15. 引入进程的目的:是为了使多个程序...

    计算机软件项目设计方案(2020).docx

    1.2.2LEAF6平台总体架构 LEAF6平台核心框架定义控制层、业务层、数据访问层的命名方式和实现规则,制定了分布式缓存、并行计算、分布式消息队列、非结构化存储可扩展技术服务的接口规范,对应用集成管理、组织机构...

    最新Python3.5零基础+高级+完整项目(28周全)培训视频学习资料

    消息队列介绍 RabbitMQ基本示例 RabbitMQ消息分发轮询 RabbitMQ消息持久化 RabbitMQ fanout广播模式 RabbitMQ direct广播模式 RabbitMQ topic细致的消息过滤广播模式 Redis string操作 RabbitMQ rpc实现 Redis hash...

    大名鼎鼎SWFUpload- Flash+JS 上传

    什么是SWFUpload?  SWFUpload是一个客户端文件上传工具...使用SWFUpload遇到的多数问题是由不正确地设置或者定义了糟糕的处理事件引起的。 初始化和设置 SWFpload必须在页面中初始化,一般可以在window.onload事件中...

    python数据结构与算法详解与源码

    4-04 单链表及结点的定义代码 4-05 单链表的判空、长度、遍历与尾部添加结点的代码实现 4-06 单链表尾部添加和在指定位置添加 4-07 单链表查找和删除元素 4-08 单链表与顺序表的对比 4-09 单向循环链表遍历和求...

    Java并发编程(学习笔记).xmind

    要解决这种活锁问题,需要在重试机制中引入随机性(randomness)。为了避免这种情况发生,需要让它们分别等待一段随机的时间 性能与可伸缩性 概念 运行速度(服务时间、延时) 处理能力(吞吐量、...

    C++ Primer第四版【中文高清扫描版】.pdf

    9.7.2 队列和优先级队列 302 小结 303 术语 303 第10章 关联容器 305 10.1 引言:pair类型 306 10.2 关联容器 308 10.3 map类型 309 10.3.1 map对象的定义 309 10.3.2 map定义的类型 310 10.3.3 给map添加元素 311 ...

    计算机二级公共基础知识

    队列中的元素是按照q1,q2,…,qn的顺序进入的,退出队列也只能按照这个次序依次退出,即只有在q1,q2,…,qn-1都退队之后,qn才能退出队列。因最先进入队列的元素将最先出队,所以队列具有先进先出的特性,体现...

    C++MFC教程

    系统会在队列中取出每一条消息,根据消息的接收句柄而将该消息发送给拥有该窗口的程序的消息循环。每一个运行的程序都有自己的消息循环,在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。而在...

    一种QoS机制下基于系统收益的IEEE802.16接纳控制算法 (2009年)

    根据协议对QoS的定义引入CSI模型计算系统综合收益,并针对计算量问题,提出新的改进模型。在MMPP队列模型下进行仿真验证,结果表明:该算法能明显区分不同业务收益,有较高的接纳率和吞吐量,并提高了带宽利用率。

    开涛高可用高并发-亿级流量核心技术

    1.3.3 流程可定义 13 1.3.4 状态与状态机 13 1.3.5 后台系统操作可反馈 14 1.3.6 后台系统审批化 14 1.3.7 文档和注释 14 1.3.8 备份 14 1.4 总结 14 第2部分高可用 17 2 负载均衡与反向代理 18 2.1 upstream配置 20...

Global site tag (gtag.js) - Google Analytics