消息队列(一)

消息队列MQ

维基百科中是这样介绍消息队列的

消息队列(Message queue)是一种进程间通信或同一进程的不同线程间的通信方式,软件的贮列用来处理一系列的输入,通常是来自用户。消息队列提供了异步的通信协议,每一个贮列中的纪录包含详细说明的数据,包含发生的时间,输入设备的种类,以及特定的输入参数,也就是说:消息的发送者和接收者不需要同时与消息队列交互。消息会保存在队列中,直到接收者取回它

58沈剑是这样介绍消息队列的

消息队列,是一种跨进程的通信机制,用于上下游传递消息。在互联网架构中,MQ是一种非常常见的上下游“逻辑解耦+物理解耦”的消息通信服务。使用MQ后,消息发送上游只需要依赖MQ,逻辑上和物理上不依赖与下游。

消息队列的应用场景

  • 异步处理: 将非核心流程异步化,提高系统响应性能。比如用户注册需要发送邮件和短信确认(虽然产品都不会这样做,仅仅举例),我们可以在注册成功后发送消息给MQ,然后邮件服务和短信服务接受消息后执行。这里,可以直接使用线程完成,但是我们可以使用MQ后,我们不用关心下游(邮件、短信服务等)有多少任务,并且我们可以简单的在下游订阅上游即可动态添加。
  • 应用解耦: 将不强依赖于本系统的非核心流程和系统流程进行解耦。比如购买商品后会有积分赠送,这里积分系统时非核心流程,我们可以让订单系统和积分系统解耦。
  • 流量削峰与流控控制: 当上下游系统处理能力存在差距的时候,利用消息队列做一个通用的“漏斗”。在下游有能力处理的时候,再进行分发。例如,在秒杀系统中我们可以把用户请求写入消息队列中,然后秒杀系统在根据规则依次从消息队列中取然后进行处理,这样就不会发送系统由于并发量过大而崩溃。
  • 消息订阅: 这里有点像UDP,上游只关心把消息放入MQ中,下游谁订阅了就会获得消息。
  • 消息通讯: MQ都会内置高效的通信机制,例如我们可以使用MQ作为通信工具进行RPC通信。
  • 日志处理: 使用MQ解决大量日志传输问题。

日志处理(转自新浪是如何分析处理32亿条实时日志的?)

电商系统(转自大型网站架构系列:分布式消息队列(一))

消息队列的不足

  • 系统更加复杂,多了MQ组件
  • 消息可靠性和重复性互为矛盾,消息不丢不重难以同时保证
  • 上游无法知道下游的执行结果

调用方实时依赖执行结果的业务场景,使用调用,而不是MQ

消息队列的消息协议

常见的MQ有RabbitMQ、ActiveMQ、Kafka、RocketMQ等等,它们支持不同的通信协议.例如AMQP、SMTP、STOMP、HTTP等等,下面是一下协议介绍。

AMQP

AMQP(高级消息队列协议)是应用层网络协议,它支持符合要求的客户端应用和消息中间件代理之间通信。

AMQP协议的各个部分

  • AMQP协议中的元素包括:Message(消息体)、Producer(生产者)、Consumer(消费者)、Virtual Host(虚拟节点)、Exchange(交换机)、Queue(队列)等
  • 由Producer(消息生产者)和Consumer(消息消费者)构成了AMQP的客户端,他们是发送消息和接收消息的主体。AMQP服务端称为Broker,一个Broker中一定包含完整的Virtual Host(虚拟主机)、 Exchange(交换机)、Queue(队列)定义
  • 一个Broker可以创建多个Virtual Host(虚拟主机),我们将讨论的Exchange和Queue都是虚拟机中的工作元素(还有User元素)。注意,如果AMQP是由多个Broker构成的集群提供服务,那么一个Virtual Host也可以由多个Broker共同构成
  • Connection是由Producer(消息生产者)和Consumer(消息消费者)创建的连接,连接到Broker物理节点上。但是有了Connection后客户端还不能和服务器通信,在Connection之上客户端会创建Channel,连接到Virtual Host或者Queue上,这样客户端才能向Exchange发送消息或者从Queue接受消息。一个Connection上允许存在多个Channel,只有Channel中能够发送/接受消息
  • Exchange元素是AMQP协议中的交换机,Exchange可以绑定多个Queue也可以同时绑定其他Exchange。消息通过Exchange时,会按照Exchange中设置的Routing(路由)规则,将消息发送到符合的Queue或者Exchange中

AMQP中消息的交互

  1. 在Producer(消息生产者)客户端建立了Channel后,就建立了到Broker上Virtual Host的连接。接下来Producer就可以向这个Virtual Host中的Exchange发送消息了
  2. Exchange(交换机)能够处理消息的前提是:它至少已经和某个Queue或者另外的Exchange形成了绑定关系,并设置好了到这些Queue和Excahnge的Routing(路由规则)。Exchange中的Routing有三种模式,在Exchange收到消息后,会根据设置的Routing(路由规则),将消息发送到符合要求的Queue或者Exchange中(路由规则还会和Message中的Routing Key属性配合使用)
  3. Queue收到消息后,可能会进行如下的处理:如果当前没有Consumer的Channel连接到这个Queue,那么Queue将会把这条消息进行存储直到有Channel被创建(AMQP协议的不同实现产品中,存储方式又不尽相同);如果已经有Channel连接到这个Queue,那么消息将会按顺序被发送给这个Channel
  4. Consumer收到消息后,就可以进行消息的处理了。但是整个消息传递的过程还没有完成:视设置情况,Consumer在完成某一条消息的处理后,将需要手动的发送一条ACK消息给对应的Queue(当然您可以设置为自动发送,或者无需发送)。Queue在收到这条ACK信息后,才会认为这条消息处理成功,并将这条消息从Queue中移除;如果在对应的Channel断开后,Queue都没有这条消息的ACK信息,这条消息将会重新被发送给另外的Channel。当然,您还可以发送NACK信息,这样这条消息将会立即归队,并发送给另外的Channel

AMQP协议中的Message

AMQP协议的消息格式如下:

其中内容在PAYLOAD部分,PAYLOAD部分格式如下:

关于AMQP更加详细的资料见于:AMQP官网关于AMQP网友的博客

STOMP

STOMP(简单文本定向协议)同样是应用层协议,它提供一个可交互操作的连接格式,容许STOMP客户端和任意STOMP消息代理(Broker)进行交互,常用于消息中间件。STOMP协议基于帧(Frame)进行通信,第一行包含命令,然后紧跟键值对形式的Header内容,第二行空行,第三行开始就是Body内容,末尾都以空字符结尾。

STOMP消息格式和HTTP请求很像,格式如下:

COMMAD
header1:value1
header2:value2
...

Body

常见帧命令有:

  • CONNECT
  • SEND
  • SUBSCRIBE
  • UNSUBSCRIBE
  • ACK
  • NACK
  • ...

例如STOMPSEND消息:

SEND
destination:/app/hello
content-length:20

{"message":"World!"}

关于STOMP资料见于:STOMP1.2官方规范关于STOMP网友的博客

JMS

JMS(Java消息服务)不是网络协议,其是Java关于消息服务提供了一组通用接口,具体实现的协议由使用该接口的应用程序实现。在MQ中ActiveMQ、RocketMQ都实现了该协议。

这里有篇介绍JMS文章:JMS学习一(JMS介绍)

Reference

http://blog.csdn.net/u012758088/article/details/78024581

https://www.cnblogs.com/my_life/articles/7002138.html

https://www.jianshu.com/p/cee941ca0c09

架构师之路工作号《到底什么时候该使用MQ?》(由于微信公众号文章URL有时间限制,所以没有列出来)

原文地址:https://www.cnblogs.com/maying3010/p/8508227.html

时间: 2024-10-09 23:48:17

消息队列(一)的相关文章

Azure Messaging-ServiceBus Messaging消息队列技术系列6-消息回执

上篇博文中我们介绍了Azure Messaging的重复消息机制.At most once 和At least once. Azure Messaging-ServiceBus Messaging消息队列技术系列5-重复消息:at-least-once at-most-once 本文中我们主要研究并介绍Azure Messaging的消息回执机制:实际应用场景: 同步收发场景下,消息生产者和消费者双向应答模式,例如:张三写封信送到邮局中转站,然后李四从中转站获得信,然后在写一份回执信,放到中转站

【转】MSMQ 微软消息队列 简单 示例

MSMQ它的实现原理是:消息的发送者把自己想要发送的信息放入一个容器中(我们称之为Message),然后把它保存至一个系统公用空间的消息队列(Message Queue)中:本地或者是异地的消息接收程序再从该队列中取出发给它的消息进行处理. 我个人的理解,你可以把他当做一种,把数据打包后,发送到一个地方,程序也可以去取到这个打包的程序,队列的机制就不讲了,并发问题荡然无存.呵呵. 上代码: 首先 using System.Messaging; public class MsmqManagerHe

消息队列(msg)

一.消息队列:从一个进程向另一个进程发送数据块,读取不一定是先入先出. 管道与消息队列区别:管道基于字节流的,消息队列基于消息: 管道只能发送字符串,消息队列有类型: 管道随进程,消息队列随内核. 二.创建函数原型:int msgget(key_t key, int msgflg);    //key由ftok生成,IPC_CREAT|IPC_EXCL 接收消息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, in

第15章 进程间通行 15.6 XSI IPC 15.7 消息队列

15.6 XSI IPC (1)3种称作XSI IPC的IPC是: 1)消息队列 2)信号量 3)共享存储器 (2)标识符和键 1)标识符:是一个非负整数,用于引用IPC结构.是IPC对象的内部名. 2)键:IPC对象的外部名.可使多个合作进程能够在同一IPC对象上汇聚. (3)IPC_PRIVATE键: 用于创建一个新的IPC结构.不能指定此键来引用一个现有的IPC结构. (4)ftok函数: 由一个路径名和项目ID产生一个键. (5)ipc_perm结构体 规定了ipc结构的权限和所有者.

XSI进程间通信-----消息队列

1. 基本特点 1) 消息队列是一个由系统内核负责存储和管理,并通过消息队列标识引用的数据链表,消息队列 和有名管道fifo的区别在: 后者一次只能放一个包,而前者则可以放很多包,这样就能处理发包快,哪包慢的问题 2) 可以通过msgget函数创建一个新的消息队列, 或获取一个已有的消息队列. 通过msgsnd函数 (send)向消息队列的后端追加消息, 通过msgrcv(receive)函数从消息队列的前端提取消息. 3) 消息队列中的每个消息单元除包含消息数据外,还包含消息类型和数据长度.消

android 中使用View的消息队列api更新数据

基本上只要继承自View的控件,都具有消息队列或者handler的一些处理方法,下面是一些handler方法以及被View封装了的方法,其底层用的基本都是handler的api. 我么开一下postDelay的定义 android.view.View  public boolean postDelayed(Runnable action, long delayMillis) {         final AttachInfo attachInfo = mAttachInfo;         

消息队列实现订单异步提交

what MSMQ(Microsoft Message Queue),微软消息队列,用于应用程序之间相互通信的一种异步传输模式.应用程序可以分布在同台机器上,也可以分布于互联的网络中的任意位置.基本原理:消息发送者把要发送的消息放入容器,也就是Message(消息),然后保存到系统公用空间的消息队列中(Message Queue)中,本地或互联位置上的消息接收程序再从队列中取出发给它的消息进行处理.消息类型可以是文本,图像,自定义对象等.消息队列分为公共队列和私有队列. why 一.用于进程间的

Windows消息队列

一 Windows中有一个系统消息队列,对于每一个正在执行的Windows应用程序,系统为其建立一个"消息队列",即应用程序队列,用来存放该程序可能 创建的各种窗口的消息.应用程序中含有一段称作"消息循环"的代码,用来从消息队列中检索这些消息并把它们分发到相应的窗口函数中.  二 Windows为当前执行的每个Windows程序维护一个「消息队列」.在发生输入事件之后,Windows将事件转换为一个「消息」并将消息放入程序的消息队列中.程序通过执行一块称之为「消息循

消息队列编程

消息队列:就是一个消息的链表.而一条消息则可看作一个记录,具有特定的格式.进程可以向中按照一定的规则添加新消息:另一些进程则可以从消息队列中读走消息 发送消息队列: #include<sys/types.h>#include<sys/msg.h>#include<sys/ipc.h>#include<stdio.h> struct msgt{ long msgtype; char msgtext[1024]; };int msg_type;char str[

Freertos-事件标志组,消息队列,信号量,二值信号量,互斥信号量

任务间的通信和同步机制  在裸机编程时,使用全局变量的确比较方便,但是在加上 RTOS 后就是另一种情况了. 使用全局变量相比事件标志组主要有如下三个问题: 1.使用事件标志组可以让 RTOS 内核有效地管理任务,而全局变量是无法做到的,任务的超时等机制需要用户自己去实现.2.使用了全局变量就要防止多任务的访问冲突,而使用事件标志组则处理好了这个问题,用户无需担心.3.使用事件标志组可以有效地解决中断服务程序和任务之间的同步问题. 事件标志组:事件标志组是实现多任务同步的有效机制之一. 每创建一